2017-10-13 30 views
1

我的表结构选择一个数据集的最新行:如何ODI

ID1 ID2 ID3 Value Last_Update_date 
10 11 12 0.1 21-SEP-17 01.46.12.623580000 PM 
10 11 12 0.2 20-SEP-17 01.46.12.623580000 PM 
10 11 12 0.3 19-SEP-17 01.46.12.623580000 PM 
20 21 22 0.4 01-SEP-17 01.46.12.623580000 PM 
20 21 22 0.5 12-SEP-17 01.46.12.623580000 PM 
20 21 22 0.4 21-SEP-17 01.46.12.623580000 PM 

我正在考虑ID1 + ID2 + ID3为复合ID,我需要提取最新的行中每个组合键。 假设对于这个组合,ID1,ID2,ID3 - > 10,11,12,我的选择查询应返回10,11,12 0.2(因为20 sep是最新的)。

我曾尝试下面的代码:

SELECT a.ID1 , 
     a.ID2, 
     a.ID3 , 
     a.value , 
     a.Last_update_date 
FROM a, 
     (SELECT ID1, 
       ID2, 
       ID3, 
       MAX(last_update_date) last_update_date 
     FROM a 
     GROUP BY ID1, 
       ID2, 
       ID3 
     ) b 
WHERE a.ID1    = b.ID1 
AND  a.ID2    = b.ID2 
AND  a.ID3    = a.ID3 
AND  a.last_update_date = b.last_update_date 

有没有写这个什么更好的办法。 我将在ODI中使用代码,所以我只能选择简单的sql函数,如group by等。 感谢

回答

1

我相信ODI支持窗口函数...

和你连接语法不好,真的不好一样,永远不会再做一次糟糕。使用显式连接(不是你需要他们在这里全部)

select x.* 
from 
(
select a.*, 
     row_number() over(partition by id1, id2, id3 order by last_update_date desc) rn 
from a 
) x 
where rn = 1 
+0

哦,我已经运行它为我的项目。谢谢 –

+0

'ROW_NUMBER()'不会给出相同的结果 - 它只会返回一行。 OP的查询将返回多行,如果它们都具有相同的最大值。 – MT0

1

使用ROW_NUMBER,你在你有相同的最大值多行的情况下,查询不会返回相同的值。你可以使用RANKDENSE_RANK代替:

SELECT ID1, 
     ID2, 
     ID3, 
     value 
     Last_update_date 
FROM (
    SELECT ID1, 
     ID2, 
     ID3, 
     value, 
     last_update_date 
     RANK() OVER (PARTITION BY id1, id2, id3 ORDER BY last_update_date DESC) 
      AS rnk 
    FROM a 
) 
WHERE rnk = 1 

然而,您使用的查询分析功能的直接等同是:

SELECT ID1, 
     ID2, 
     ID3, 
     value 
     Last_update_date 
FROM (
    SELECT ID1, 
     ID2, 
     ID3, 
     value, 
     last_update_date 
     MAX(last_update_date) OVER (PARTITION BY id1, id2, id3) 
      AS max_last_update_date 
    FROM a 
) 
WHERE last_update_date = max_last_update_date