繁体   English   中英

SQL Server ROW_NUMBER()问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM