[英]SQL Server ROW_NUMBER() Issue
我正在使用row_number()表达式,但没有得到预期的结果。 我有一个sql表,有些行是重复的。 它们具有相同的“ BATCHID”,我想为它们获取第二行号,对于其他人,我使用第一行号。 我该怎么做?
SELECT * FROM (SELECT * , ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t
WHERE Rn=1
这段代码仅向我返回第一行,但我想为重复项获得第二行。
ROW_NUMBER()
为每一行赋予唯一的计数器。 您想使用RANK()
,这很相似,但是给具有相同值的行赋予相同的分数:
SELECT *
FROM (SELECT * , RANK() OVER (PARTITION BY batchid ORDER BY scaqry) rk
FROM sayimdcpc) t
WHERE rk = 1
如果某些值仅显示一次,而某些值显示两次(也许两次以上),则您不希望“第一”行,而想要“ max”行。 尝试逆转您的订单条件:
SELECT *
FROM (SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY DESC) Rn
FROM SAYIMDCPC ) t
WHERE Rn=1
附带说明一下,最好将所有列都明确列出。 例如,您可能不需要此查询之外的Rn
...
只需尝试一下,
SELECT * FROM (SELECT * , ROW_NUMBER() OVER (ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t
WHERE Rn=1
请尝试这个。 它将选择最大行数,如果没有重复,则应为第一个,否则为第二个
select * from (SELECT * , ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) d,
(SELECT batchid,max(Rn) maxRn FROM (SELECT * , ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t
group by batchid) q
where d.batchid = q.batchid and d.rn = q.maxrn
换句话说,这听起来像是在说:“当批次ID有一行时,请返回该行。如果有2行或更多行,请返回第二行。” 这将需要检查您的Rn
值以查看其最大值。 我认为您无法在单个查询中做到这一点。
所以我会尝试这样的事情:
WITH NumberedRows AS (
SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn
FROM SAYIMDCPC
)
, MaxNumber AS (
SELECT Max(RN) as MaxRn,
BATCHID
FROM NumberedRows
GROUP BY BATCHID
)
, NonDupes AS (
SELECT *
FROM NumberedRows
WHERE BATCHID NOT IN (SELECT BATCHID FROM MaxNumber WHERE MaxNumber = 1)
)
, SecondRows AS (
SELECT (
FROM NumberedRows
WHERE BATCHID NOT IN (SELECT BATCHID FROM MaxNumber WHERE MaxNumber > 1)
AND Rn = 2
)
SELECT
FROM NonDupes
UNION ALL
SELECT *
FROM SecondRows
包含重复项和不重复项的总结果集。 第一列“ IsDuplicate”指示该列是否重复。
;WITH d1 AS (
SELECT Seq = ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY)
,*
FROM SAYIMDCPC
)
SELECT IsDuplicate = CONVERT(BIT, Seq)
,*
FROM d1
这只会给您重复项:
;WITH d1 AS (
SELECT Seq = ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY)
,*
FROM SAYIMDCPC
)
SELECT IsDuplicate = CONVERT(BIT, Seq)
,*
FROM d1
WHERE Seq > 1
这只会给您非重复项(如您的第一个查询)
;WITH d1 AS (
SELECT Seq = ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY)
,*
FROM SAYIMDCPC
)
SELECT IsDuplicate = CONVERT(BIT, Seq)
,*
FROM d1
WHERE Seq = 1
如果我错了请纠正我
e.g sample data
BatchID, SCAQTY
1 , 10
2 , 10
2 , 20
2 , 30
您的期望结果如下吗?
**Expectation Result 1**
BatchID , SCAQty
1 , 10
2 , 30
要么
**Expectation Result 2**
BatchID , SCAQty
1 , 10
2 , 20
2 , 30
根据我的理解,您想要执行的是期望结果1,所以我想下面的查询应该可以帮助您,您只需要在查询中添加SCAQTY的desc
SELECT * FROM (SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY DESC) Rn FROM SAYIMDCPC ) t
WHERE Rn=1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.