创建一个SQL查询从两个表中
问题描述:
检索数据我有两个表:创建一个SQL查询从两个表中
T_STOCK
:主键是id
,seller
,和其他一些领域,让说a
和b
。 T_FLOW
:主键是(id
+ startdate
)以及其他一些字段,例如c
和d
。
我想返回从T_STOCK
关于特定seller
每个记录的所有列的查询,但在T_FLOW
表中的列(startDate
,c
和d
)完成。
T_STOCK
和T_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 |
+----+--------+---+---+------------+----+----+
我怎样写我的查询呢?
答
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
)
答
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)
你的关系似乎有点怪我。你的股票'PK'是'(id,seller)',你可以拥有两个具有相同'id'的股票,但流量只与'id'相关。这是故意的吗? – Quassnoi 2010-01-15 11:46:46
+1为您的ASCII艺术! – 2010-01-15 11:49:14
@Quassnoi,是的,这是故意的:) – romaintaz 2010-01-15 12:38:47