[英]Subquery to return multiple columns from newest record?
我得到了這樣的表結構:
文獻
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
我想要得到的輸出是來自HISTORY
(最高HID)中最新記錄的NAME
, DATA
和HDATA1
, HDATA2
和HDATA3
值HDATA2
, HDATA3
值與Documents
表中的相應ID匹配。
我發現的示例僅從一列返回一個值,但是我需要來自多列的數據。 我不知道如何設置此SQL。
以下示例適用於Oracle,並且可能會略微適應不同的SQL方言:
SELECT *
FROM ( SELECT h.*,
d.*,
RANK() OVER (PARTITION BY h.DOC_ID ORDER BY h.HID DESC) AS RNK
FROM History h
JOIN Document d ON d.ID = h.DOC_ID )
WHERE RNK = 1
經過以下數據測試:
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
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
以下查詢將返回每個文檔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
通過在這種情況下使用交叉應用,查詢成本將相對較低。它可以在查詢估計的執行計划中顯示最佳結果。
使用排序子句中的窗口函數row_number
結合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
);
它為每個文檔返回具有最新歷史記錄ID的一條記錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.