Row_Num 案例
CASE with Row_Num
我在 SQL Server 2016 中有一个 table,其中每个唯一的 PartnerNumber 都有多个 ConnectorId 值和多个 CommissionDate
我的要求是,当我在最终结果中查询 table 时,我应该只获取 rn = 1 的行,这是使用下面的查询工作的,但在这个例子中,P1 按照当前逻辑它选择 rn = 1 的行,但我还想要的是,如果 rn = 1 的 CommissionDate 为 NULL,那么在这种情况下,显示 rn = 2 的值,如果不为 null,则继续 rn = 1
Table 脚本:
CREATE table #Final_Data
(
CommissionDate date,
PartnerNumber varchar(50),
Connector_Id varchar(50),
)
GO
insert into #Final_Data (CommissionDate,PartnerNumber,Connector_Id)
VALUES (NULL,'P1','C1'), ('2017-12-27','P1','C2')
,('2015-09-14','P2','C3'),('2011-09-13','P2','C4')
,(NULL,'P3','C5'),(NULL,'P3','C6')
GO
查询:
;WITH CTE
AS
(
SELECT CommissionDate,PartnerNumber,Connector_Id,
ROW_NUMBER() OVER (Partition by PartnerNumber ORDER BY CommissionDate asc) AS rn
FROM #Final_Data
)
SELECT TOP 9999999 * FROM CTE where rn = 1
ORDER BY PartnerNumber
实际输出:
CommissionDate PartnerNumber Connector_Id rn
NULL P1 C1 1
2011-09-13 P2 C4 1
NULL P3 C5 1
预期输出:
CommissionDate PartnerNumber Connector_Id rn
2017-12-27 P1 C2 2
2011-09-13 P2 C4 1
NULL P3 C5 1
您可以在 window 函数的 order by
子句中使用条件排序:
ROW_NUMBER() OVER (
PARTITION BY PartnerNumber
ORDER BY CASE WHEN CommissionDate IS NOT NULL THEN 0 ELSE 1 END,
CommissionDate
) AS rn
GMB 的回答是正确的。但是,它通常更简洁地表示为:
ROW_NUMBER() OVER (
PARTITION BY PartnerNumber
ORDER BY COALESCE(CommissionDate, '9999-01-01')
) AS rn
这允许 ORDER BY
只有一把钥匙。对于 SQL 标准语法,它本质上是 shorthand:
ROW_NUMBER() OVER (
PARTITION BY PartnerNumber
ORDER BY CommissionDate NULLS LAST
) AS rn
哪个 SQL 服务器(还???)不支持。
我在 SQL Server 2016 中有一个 table,其中每个唯一的 PartnerNumber 都有多个 ConnectorId 值和多个 CommissionDate
我的要求是,当我在最终结果中查询 table 时,我应该只获取 rn = 1 的行,这是使用下面的查询工作的,但在这个例子中,P1 按照当前逻辑它选择 rn = 1 的行,但我还想要的是,如果 rn = 1 的 CommissionDate 为 NULL,那么在这种情况下,显示 rn = 2 的值,如果不为 null,则继续 rn = 1
Table 脚本:
CREATE table #Final_Data
(
CommissionDate date,
PartnerNumber varchar(50),
Connector_Id varchar(50),
)
GO
insert into #Final_Data (CommissionDate,PartnerNumber,Connector_Id)
VALUES (NULL,'P1','C1'), ('2017-12-27','P1','C2')
,('2015-09-14','P2','C3'),('2011-09-13','P2','C4')
,(NULL,'P3','C5'),(NULL,'P3','C6')
GO
查询:
;WITH CTE
AS
(
SELECT CommissionDate,PartnerNumber,Connector_Id,
ROW_NUMBER() OVER (Partition by PartnerNumber ORDER BY CommissionDate asc) AS rn
FROM #Final_Data
)
SELECT TOP 9999999 * FROM CTE where rn = 1
ORDER BY PartnerNumber
实际输出:
CommissionDate PartnerNumber Connector_Id rn
NULL P1 C1 1
2011-09-13 P2 C4 1
NULL P3 C5 1
预期输出:
CommissionDate PartnerNumber Connector_Id rn
2017-12-27 P1 C2 2
2011-09-13 P2 C4 1
NULL P3 C5 1
您可以在 window 函数的 order by
子句中使用条件排序:
ROW_NUMBER() OVER (
PARTITION BY PartnerNumber
ORDER BY CASE WHEN CommissionDate IS NOT NULL THEN 0 ELSE 1 END,
CommissionDate
) AS rn
GMB 的回答是正确的。但是,它通常更简洁地表示为:
ROW_NUMBER() OVER (
PARTITION BY PartnerNumber
ORDER BY COALESCE(CommissionDate, '9999-01-01')
) AS rn
这允许 ORDER BY
只有一把钥匙。对于 SQL 标准语法,它本质上是 shorthand:
ROW_NUMBER() OVER (
PARTITION BY PartnerNumber
ORDER BY CommissionDate NULLS LAST
) AS rn
哪个 SQL 服务器(还???)不支持。