문제

I'm using row_number() expression but I don't get result as I expected. I have a sql table and some rows are duplicate. They have same 'BATCHID' and I want to get second row number for these, for others I use first row number. 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. You'd want to use RANK(), which is similar, but gives rows with identical values the same score:

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. 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...

Simply try this,

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

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." That's going to require inspecting your Rn value to see what its max is. 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

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

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

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

Total result set with duplicates and non duplicates. The first column "IsDuplicate" indicates if the column is a duplicate or not.

;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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top