簡體   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