简体   繁体   English

SQL Server ROW_NUMBER()问题

[英]SQL Server ROW_NUMBER() Issue

I'm using row_number() expression but I don't get result as I expected. 我正在使用row_number()表达式,但没有得到预期的结果。 I have a sql table and some rows are duplicate. 我有一个sql表,有些行是重复的。 They have same 'BATCHID' and I want to get second row number for these, for others I use first row number. 它们具有相同的“ BATCHID”,我想为它们获取第二行号,对于其他人,我使用第一行号。 How can I do it? 我该怎么做?

SELECT * FROM (SELECT * , ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t 
WHERE Rn=1

This code returns to me only first rows, but I want to get second rows for duplicated items. 这段代码仅向我返回第一行,但我想为重复项获得第二行。

ROW_NUMBER() gives every row a unique counter. ROW_NUMBER()为每一行赋予唯一的计数器。 You'd want to use RANK() , which is similar, but gives rows with identical values the same score: 您想使用RANK() ,这很相似,但是给具有相同值的行赋予相同的分数:

SELECT * 
FROM   (SELECT * , RANK() OVER (PARTITION BY batchid ORDER BY scaqry) rk 
        FROM   sayimdcpc) t 
WHERE  rk = 1

If some values are only shown once, but some twice (and perhaps more than twice), you don't want the "first" row, you want the "max" row. 如果某些值仅显示一次,而某些值显示两次(也许两次以上),则您不希望“第一”行,而想要“ max”行。 Try reversing your order condition: 尝试逆转您的订单条件:

SELECT * 
FROM (SELECT * , 
             ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY DESC) Rn 
      FROM SAYIMDCPC ) t 
WHERE Rn=1

As a side note, it's still better to explicitly list out all columns; 附带说明一下,最好将所有列都明确列出。 for instance, you probably don't need Rn outside of this query... 例如,您可能不需要此查询之外的Rn ...

Simply try this, 只需尝试一下,

SELECT * FROM (SELECT * , ROW_NUMBER() OVER (ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t 
WHERE Rn=1

Please try this. 请尝试这个。 It will select max row num, if no duplicate then it should be first one otherwise second 它将选择最大行数,如果没有重复,则应为第一个,否则为第二个

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

To rephrase it another way, it sounds like you're saying, "When there's a single row for the Batch ID, return the single row. When there are 2 or more rows, return the second row." 换句话说,这听起来像是在说:“当批次ID有一行时,请返回该行。如果有2行或更多行,请返回第二行。” That's going to require inspecting your Rn value to see what its max is. 这将需要检查您的Rn值以查看其最大值。 I don't think you can do it in a single query. 我认为您无法在单个查询中做到这一点。

So I'd try something like this: 所以我会尝试这样的事情:

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

Total result set with duplicates and non duplicates. 包含重复项和不重复项的总结果集。 The first column "IsDuplicate" indicates if the column is a duplicate or not. 第一列“ IsDuplicate”指示该列是否重复。

;WITH d1 AS (
    SELECT Seq = ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) 
          ,*
    FROM SAYIMDCPC
)

SELECT  IsDuplicate = CONVERT(BIT, Seq)
       ,* 
FROM d1

This will give you only the duplicates: 这只会给您重复项:

;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

This will give you only the non duplicates (as in your first query) 这只会给您非重复项(如您的第一个查询)

;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

correct me if i am wrong 如果我错了请纠正我

e.g sample data

BatchID, SCAQTY
  1    ,  10
  2    ,  10
  2    ,  20
  2    ,  30

is your expectation result like below? 您的期望结果如下吗?

**Expectation Result 1**
BatchID , SCAQty
 1      ,  10
 2      ,  30

or 要么

**Expectation Result 2**
BatchID , SCAQty
  1     ,   10
  2     ,   20
  2     ,   30

based on my understanding what you want to perform is Expectation Result 1, so i guess Query below should able to help u, you just need to add desc for SCAQTY in your query 根据我的理解,您想要执行的是期望结果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