选择一组第二低的值
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
我有两列兴趣 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