需要帮助在DB2

时间:2016-07-28 14:53:28

标签: sql select db2 left-join greatest-n-per-group

我还没有在大学完成相关课程,所以我不能确定这个查询是否正确,它有效,但看起来太奇怪了所以我需要复习和一些反馈。

我的以下IP_TABLE表包含混合主键:ID + IP

----------------------------------
|  ID  | DATE      | IP          |
----------------------------------
|  1   | 2016-10-01| 1.2.3.10    |
----------------------------------
|  2   | 2016-10-20| 1.2.3.20    |
----------------------------------
|  2   | 2016-10-25| 1.2.3.40    |
----------------------------------
|  3   | 2016-10-01| 1.2.3.10    |
----------------------------------
|  3   | 2016-10-25| 1.2.3.25    |
----------------------------------

我想获取数据在相同ID中具有最大值的所有行,如下所示:

----------------------------------
|  ID  | DATE      | IP          |
----------------------------------
|  1   | 2016-10-01| 1.2.3.10    |
----------------------------------
|  2   | 2016-10-25| 1.2.3.40    |
----------------------------------
|  3   | 2016-10-25| 1.2.3.25    |
----------------------------------

现在我有两个查询来完成这项工作:

SELECT * FROM (SELECT ID, MAX(DATE) AS LAST_DATE
                    FROM IP_TABLE 
                GROUP BY ID
                    ORDER BY MAX(DATE) ASC) AS T1
            LEFT JOIN IP_TABLE AS T2
                ON T1.ID = T2.ID
                    AND T1.LAST_DATE = T2.DATE

我把桌子连接到自己看起来很奇怪,不知道是不是正确。

第二个工作查询如下:

SELECT * FROM IP_TABLE AS T1
    WHERE DATE = (SELECT MAX(DATE) FROM IP_TABLE WHERE ID = T1.ID)

它担心此查询会导致性能影响,因为它看起来像是O(n ^ 2),即它在所有行中看到的每一行。

1 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER之类的窗口函数:

SELECT ID, DATE, IP
FROM (
   SELECT ID, DATE, IP,
          ROW_NUMBER() OVER (PARTITION BY ID 
                             ORDER BY DATE DESC) AS rn      
   FROM IP_TABLE) AS t
WHERE t.rn = 1

ROW_NUMBER枚举每个ID切片中的记录,从具有最新DATE值的记录开始(由于ORDER BY DATE DESC子句)。因此,外部查询选择最新的每{ - 1}}记录。