创建一个SQL查询从两个表中

问题描述:

检索数据我有两个表:创建一个SQL查询从两个表中

T_STOCK:主键是idseller,和其他一些领域,让说abT_FLOW:主键是(id + startdate)以及其他一些字段,例如cd

我想返回从T_STOCK关于特定seller每个记录的所有列的查询,但在T_FLOW表中的列(startDatecd)完成。

T_STOCKT_FLOW之间的关系基于id属性。 每当T_STOCK中存在具有特定ID的记录时,此ID至少有一条记录存在于T_FLOW中。

然而,可能发生不止一个纪录T_FLOW存在。在这种情况下,我只能考虑最近的(即max(startDate))。

在别人的话,如果我们有以下的表格内容:

+---------------------+ 
|  T_STOCK  | 
+----+--------+---+---+ 
| ID | SELLER | a | b | 
+----+--------+---+---+ 
| 01 | foobar | 1 | 2 | 
+----+--------+---+---+ 
| 02 | foobar | 3 | 4 | 
+----+--------+---+---+ 
| 03 | foobar | 5 | 6 | 
+----+--------+---+---+ 

+---------------------------+ 
|   T_FLOW   | 
+----+------------+----+----+ 
| ID | StartDate | c | d | 
+----+------------+----+----+ 
| 01 | 01/01/2010 | 7 | 8 | 
+----+------------+----+----+ 
| 02 | 01/01/2010 | 9 | 10 | 
+----+------------+----+----+ 
| 02 | 07/01/2010 | 11 | 12 | 
+----+------------+----+----+ 
| 03 | 03/01/2010 | 13 | 14 | 
+----+------------+----+----+ 
| 03 | 05/01/2010 | 15 | 16 | 
+----+------------+----+----+ 

查询的结果一定是:

+----+--------+---+---+------------+----+----+ 
| ID | SELLER | a | b | startDate | c | d | 
+----+--------+---+---+------------+----+----+ 
| 01 | foobar | 1 | 2 | 01/01/2010 | 7 | 8 | 
+----+--------+---+---+------------+----+----+ 
| 02 | foobar | 3 | 4 | 03/01/2010 | 11 | 12 | 
+----+--------+---+---+------------+----+----+ 
| 03 | foobar | 5 | 6 | 01/01/2010 | 15 | 16 | 
+----+--------+---+---+------------+----+----+ 

我怎样写我的查询呢?

+0

你的关系似乎有点怪我。你的股票'PK'是'(id,seller)',你可以拥有两个具有相同'id'的股票,但流量只与'id'相关。这是故意的吗? – Quassnoi 2010-01-15 11:46:46

+1

+1为您的ASCII艺术! – 2010-01-15 11:49:14

+0

@Quassnoi,是的,这是故意的:) – romaintaz 2010-01-15 12:38:47

SELECT * 
FROM t_stock s 
JOIN (
     SELECT f.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY startDate DESC) AS rn 
     FROM t_flow f 
     ) f 
ON  f.id = s.id 
     AND f.rn = 1 

下面是不使用分析功能的解决方案:

SELECT * 
FROM t_stock s 
JOIN t_flow f 
ON  (f.id, f.startDate) = 
     (
     SELECT id, MAX(startDate) 
     FROM t_flow fi 
     WHERE fi.id = s.id 
     GROUP BY 
       id 
     ) 
+0

是否有任何解决方案来写这个查询,而无需使用'ROW_NUMBER()以上(分区...'? – romaintaz 2010-01-15 13:22:39

SELECT DISTINCT 
     s.* 
     ,FIRST_VALUE(f.startdate) 
     OVER (PARTITION BY f.id ORDER BY f.startdate DESC) startdate 
     ,FIRST_VALUE(f.c) 
     OVER (PARTITION BY f.id ORDER BY f.startdate DESC) c 
     ,FIRST_VALUE(f.d) 
     OVER (PARTITION BY f.id ORDER BY f.startdate DESC) d 
FROM t_stock s, t_flow f 
WHERE f.id = s.id 

您使用分析,as shown by Quassnoi,或使用获得最新的T_FLOW记录:

select id, max(startdate) last_start_date from t_flow group by id; 

然后你可以加入你的T_STOCK表格 - 例如:

select 
    s.*, 
    f.* 
from 
    t_stock s 
     inner join t_flow f on 
       f.id = s.id 
      and (f.id, f.startdate) in 
       (
       select 
        id, 
        max(startdate) laststartdate 
       from 
        t_flow 
       group by 
        id 
       ) 
+0

你需要一个更加入从't_flow'得到其他列。 – Quassnoi 2010-01-15 13:48:36

+0

我作为mid-edit :) - 并且仍然不起作用 – 2010-01-15 13:51:39

+0

这应该是'(f.id,f.startdate)IN ...' – Quassnoi 2010-01-15 13:55:13

select id, max(startdate) last_start_date from t_flow group by id; 

然后你就可以像这样与你T_STOCK表,什么加入这个:

select s.*, f.* from t_stock s inner join t_flow f on f.id = s.id 
and (f.id, f.startdate) in (select id, max(startdate) laststartdate 
       from t_flow group by id)