选择一组第二低的值

selecting set of second lowest values

我有两列兴趣 ID 和截止日期:

ID    Deadline (DD/MM/YYYY)
1        01/01/2017
1        05/01/2017
1        04/01/2017
2        02/01/2017
2        03/01/2017  
2        06/02/2017
2        08/03/2017

每个 ID 可以有多个 (n) 个截止日期。我需要 select 每个 ID 的截止日期第二低的所有行。

期望的输出:

ID    Deadline (DD/MM/YYYY)
1        04/01/2017
2        03/01/2017  

选择最小值可以通过以下方式完成:

select min(deadline) from XXX group by ID

但我迷失了 "middle" 值。我正在使用 Rpostgresql,但任何想法也有帮助。

感谢您的帮助

一种方法是使用 ROW_NUMBER() window 函数

SELECT id, deadline
  FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY deadline) rn
      FROM xxx 
  ) q
 WHERE rn = 2 -- get only second lowest ones

LATERAL

SELECT t.*
  FROM (
    SELECT DISTINCT id FROM xxx
  ) i JOIN LATERAL (
    SELECT *
      FROM xxx
     WHERE id = i.id
     ORDER BY deadline 
     OFFSET 1 LIMIT 1
  ) t ON (TRUE)

输出:

 id |  deadline
----+------------
  1 | 2017-04-01
  2 | 2017-03-01

这是一个dbfiddle演示

在获取 distinct 记录后使用 ROW_NUMBER() 将消除获得最低日期而不是次低日期的机会如果有重复的记录。

select ID,Deadline 
    from (
        select ID,
        Deadline, 
        ROW_NUMBER() over(partition by ID order by Deadline) RowNum 
        from (select distinct ID, Deadline from SourceTable) T
        ) Tbl
        where RowNum = 2