SQL Server - 带有 PARTITION 的 ROW_NUMBER(),如何获取多条记录?
Posted
技术标签:
【中文标题】SQL Server - 带有 PARTITION 的 ROW_NUMBER(),如何获取多条记录?【英文标题】:SQL Server - ROW_NUMBER() with PARTITION, how to get multiple records? 【发布时间】:2021-02-12 20:51:06 【问题描述】:我正在为我的查询而苦苦挣扎
SELECT * FROM (
SELECT ins.ID, ins.UnitElement_ID, ins.Date, ue.Code,
ROW_NUMBER() OVER (PARTITION BY ins.UnitElement_ID ORDER BY ins.Date DESC) AS lastAnomaly
FROM Inspection ins
INNER JOIN UnitElement ue ON ins.UnitElement_ID = ue.ID
INNER JOIN InspectionedAnomaly ia ON ia.Inspection_ID = ins.ID
WHERE ins.UnitElement_ID IN (3,10)
AND ins.Evaluation IS NOT NULL
) selectedAnomaly
输出结果是
ID UnitElement_ID Date Code lastAnomaly
0 3020217 3 2020-10-30 12:09:50 F01001G2 1
1 3020217 3 2020-10-30 12:09:50 F01001G2 2
2 3020217 3 2020-10-30 12:09:50 F01001G2 3
3 3009055 10 2020-05-04 00:00:00 F01001M1 1
4 3009055 10 2020-05-04 00:00:00 F01001M1 2
5 3020224 10 2020-05-04 00:00:00 F01001M1 3
6 3020224 10 2020-05-04 00:00:00 F01001M1 4
7 670231 10 2019-07-23 00:00:00 F01001M1 5
8 670231 10 2019-07-23 00:00:00 F01001M1 6
9 576227 10 2018-11-05 00:00:00 F01001M1 7
当我添加 Where 子句 WHERE lastAnomaly = 1
时,它工作得很好,但是当我的日期与“最近”日期相同(例如第 0,1 和 2 行)时,就会出现问题。
如果最近的日期相同,有没有办法提取 sql 查询中的所有 3 行?
谢谢大家
【问题讨论】:
是的,然后使用RANK
或DENSE_RANK
而不是ROW_NUMBER
。
使用RANK()
或DENSE_RANK()
代替ROW_NUMBER()
。
标记时,请仅标记您真正使用的RDBMS。 mysql 和 SQL Server 是 2 个完全不同的 RDBMS
【参考方案1】:
使用rank()
和过滤:
SELECT *
FROM (SELECT ins.ID, ins.UnitElement_ID, ins.Date, ue.Code,
RANK() OVER (PARTITION BY ins.UnitElement_ID ORDER BY ins.Date DESC) AS lastAnomaly
FROM Inspection ins JOIN
UnitElement ue
ON ins.UnitElement_ID = ue.ID JOIN
InspectionedAnomaly ia
ON ia.Inspection_ID = ins.ID
WHERE ins.UnitElement_ID IN (3, 10) AND
ins.Evaluation IS NOT NULL
) sa
WHERE lastAnomaly = 1;
或者,如果您愿意,可以使用MAX()
:
MAX(ins.DATE) OVER (PARTITION BY ins.UnitElement_ID) AS lastAnomalyDate
. . .
WHERE lastAnomalyDate = DATE
【讨论】:
【参考方案2】:使用rank()
代替row_number()
。它为与OVER()
子句的ORDER BY
关联的行分配相同的排名。
所以:
SELECT *
FROM (
SELECT ins.ID, ins.UnitElement_ID, ins.Date, ue.Code,
RANK() OVER (PARTITION BY ins.UnitElement_ID ORDER BY ins.Date DESC) AS lastAnomaly
FROM Inspection ins
INNER JOIN UnitElement ue ON ins.UnitElement_ID = ue.ID
INNER JOIN InspectionedAnomaly ia ON ia.Inspection_ID = ins.ID
WHERE ins.UnitElement_ID IN (3,10)
AND ins.Evaluation IS NOT NULL
) selectedAnomaly
WHERE lastAnomaly = 1
【讨论】:
以上是关于SQL Server - 带有 PARTITION 的 ROW_NUMBER(),如何获取多条记录?的主要内容,如果未能解决你的问题,请参考以下文章
转载:SQL Server 2008-建立分区表(Table Partition) 转载
SQL Server: Difference between PARTITION BY and GROUP BY
SQL SERVER OVER PARTITION 业务案例
SQL Server:循环遍历每个(PARTITION BY ...)元素的过程或函数