我有一个像这样的表结构:
文档
ID | NAME | DATA
----+-------+--------
1 | Doc1 | Data1
2 | Doc2 | Data2
记录:
HID | DOC_ID | HDATA1 | HDATA2 | HDATA3
----+-----------+-----------+-----------+---------
1 | 1 | A | B | C
2 | 2 | C | D | E
3 | 1 | A | A | B
4 | 1 | B | B | D
5 | 2 | E | A | C
我想要获得的输出是{{1}中最新记录的字段NAME
,DATA
和HDATA1
,HDATA2
和HDATA3
值(最高HID)与HISTORY
表中的相应ID匹配。
我发现的示例只返回一列中的一个值,但我需要来自多个列的数据。我无法想象如何设置这个SQL。
答案 0 :(得分:2)
以下示例适用于Oracle,可能会针对不同的SQL方言稍作调整:
INSERT INTO Document VALUES ( 1 , 'Doc1' , 'Data1' );
INSERT INTO Document VALUES ( 2 , 'Doc2' , 'Data2' );
INSERT INTO History VALUES ( 1 , 1 , 'A' , 'B' , 'C' );
INSERT INTO History VALUES ( 2 , 2 , 'C' , 'D' , 'E' );
INSERT INTO History VALUES ( 3 , 1 , 'A' , 'A' , 'B' );
INSERT INTO History VALUES ( 4 , 1 , 'B' , 'B' , 'D' );
INSERT INTO History VALUES ( 5 , 2 , 'E' , 'A' , 'C' );
使用以下数据进行测试:
HID DOC_ID HDATA1 HDATA2 HDATA3 ID NAME DATA RNK
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
4 1 B B D 1 Doc1 Data1 1
5 2 E A C 2 Doc2 Data2 1
结果:
row_number
答案 1 :(得分:0)
select * from Document d
inner join (
select h1.* from History h1
inner join (
select max(hid) as hid from History group by doc_id
) h2
on h1.hid = h2.hid
) t
on t.doc_id = d.doc_id
答案 2 :(得分:0)
以下查询将返回每个文档ID的最新记录
SELECT
ID, Name, DATA, HDATA1, HDATA2, HDATA3
FROM Document D CROSS APPLY (SELECT TOP 1 HDATA1, HDATA2, HDATA3 FROM History H WHERE D.ID=H.DOC_ID ORDER BY H.HID DESC) A
在此方案中使用交叉应用查询成本相对较低。 它可以在查询估计执行计划中显示最佳结果。
答案 3 :(得分:0)
使用与TOP 1 with ties
结合的排序子句中的窗口函数select top 1 with ties *
from document d
join history h
d.id = h.doc_id
order by row_number() over (
partition by d.id
order by h.hid desc
);
,有一种非常优雅的方法可以实现这一点。不需要子查询。
{{1}}
每个文档返回一条记录,其中包含最新的历史记录ID。