子查询从最新记录返回多个列?

时间:2017-10-18 05:41:59

标签: sql sql-server subquery multiple-columns

我有一个像这样的表结构:

文档

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}中最新记录的字段NAMEDATAHDATA1HDATA2HDATA3值(最高HID)与HISTORY表中的相应ID匹配。

我发现的示例只返回一列中的一个值,但我需要来自多个列的数据。我无法想象如何设置这个SQL。

4 个答案:

答案 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。