【发布时间】:2017-02-15 14:14:13
【问题描述】:
我有这样的声明:
select REFNUMBER,
SomeDate,
Somecolumn1,
Somecolumn2
from Table
如何选择与按 REFNUMBER 分组的最低日期关联的行?
【问题讨论】:
标签: sql oracle greatest-n-per-group
我有这样的声明:
select REFNUMBER,
SomeDate,
Somecolumn1,
Somecolumn2
from Table
如何选择与按 REFNUMBER 分组的最低日期关联的行?
【问题讨论】:
标签: sql oracle greatest-n-per-group
使用ROW_NUMBER()解析函数:
SELECT *
FROM (
SELECT REFNUMBER,
SomeDate,
Somecolumn1,
Somecolumn2,
ROW_NUMBER() OVER ( PARTITION BY REFNUMBER ORDER BY SomeDate ) As rn
FROM Table
)
WHERE rn = 1
【讨论】:
使用first/last 聚合函数并避免子查询:
select refnumber,
min(somedate) as somedate,
min(somecolumn1) keep (dense_rank first order by somedate) as somecolumn1,
min(somecolumn2) keep (dense_rank first order by somedate,
somecolumn1) as somecolumn2
from table_name
group by refnumber
【讨论】:
somedate 列有多个具有相同最小值的行,则有可能从不同行获取值。想象一下第 1 行:1, 2017-01-01 00:00:00, 10, 0 和第 2 行:1, 2017-01-01 00:00:00, 0, 10,那么输出将是 1, 2017-01-01 00:00:00, 0, 0,它从两行中获取值。您可以在聚合中使用ORDER BY somedate, ROWNUM 来修复它(或其他生成行的确定性排序的方法,以确保仅考虑单行)。
somecolumn1 添加到应用于somecolumn2 的first 函数中的order by。谢谢你指出;大约一半的时间我记得做对,大约一半的时间我不记得。
如果一个 REFNUMBER 有多个相同的最低日期,这将给出该 REFNUMBER 的所有最小日期行。 (不止一个)
SELECT Table.* FROM Table
INNER JOIN (SELECT REFNUMBER, MIN(SomeDate) AS mindt FROM Table GROUP BY REFNUMBER) t
ON
Table.REFNUMBER = t.REFNUMBER AND Table.SomeDate = t.mindt
【讨论】:
rank() 或 dense_rank()(在这种情况下它们将给出相同的结果)而不是 @987654324 @.