2016-08-11 4 views
0

다음 데이터를 반환하는 쿼리를 작성했습니다. RowNum가> 1이다SQL에서 RowNum의 조건부 선택

ID EmpFirstName EmpLastName RowNum 
1  X     Y  1 
2  A     B  1 
3  A     B  2 

는 지금은 모든 레코드를 원한다. 예를 들어,이 경우에는 출력에 2와 3 개의 레코드가 필요합니다.

조건을 넣으면 RowNum >1을 입력하면 세 번째 레코드 만 나오지만 2도 필요합니다.

select ID, EmpFirstName, EmpLastName, 
ROW_NUMBER() OVER (PARTITION BY EmpFirstName, EmpLastName ORDER BY ID) AS RowNum 
FROM aTable 

이 중복 된 값을 필터링하는 데 사용되는 고전적인 쿼리입니다 : 조회를 가정

+0

두 번째 레코드가'RowNum' ='을 1'이있는 경우는, 왜 당신은 당신의 결과에 설정하는 것이할까요? 이것은 나에게 모순되는 것처럼 들린다. –

+0

사실 @TimBiegeleisen 세트에 중복 레코드가 있으면 전체 레코드 정보가 필요합니다. 원래의 데이터 세트에는 많은 필드가 있으며 분명히 중복은 삭제되지만 결정을 내리기 위해서는 두 레코드 모두 출력이 필요합니다. 'RowNum = 2'을 선택하면 2 차 레코드 또는 1 차 레코드를 삭제할지 여부를 결정할 수 없습니다. –

+0

첫 번째와 두 번째 행이 중복 된 것을 볼 수 있지만 'RowNum'값은 여전히 ​​1 미만입니다. –

답변

1

이있다.

효과적으로 나는 COUNT() 윈도우 기능을 사용하는 것이 좋습니다 수있는 중복 값을 가진 모든 레코드를 선택 위해서는 :

drop table #tmp 
CREATE table #tmp (ID int , EmpFirstName varchar(10) , EmpLastName varchar(10)) 
go 
INSERT INTO #tmp VALUES 
    (1,'X','Y') 
    ,(2,'A','B') 
    ,(3,'A','B') 
    ,(4,'A','C') 
    ,(5,'B','C') 
    ,(6,'B','C') 


;with a as (
    select ID, EmpFirstName, EmpLastName, 
    ROW_NUMBER() OVER (PARTITION BY EmpFirstName, EmpLastName ORDER BY ID) AS RowNum, 
    COUNT(id) OVER (PARTITION BY EmpFirstName, EmpLastName) AS cnt 
    FROM #tmp 
) 
SELECT * FROM a where cnt > 1 
ORDER BY EmpFirstName, EmpLastName 

결과 :

가이 쿼리를 사용

;with a as (
    select ID, EmpFirstName, EmpLastName, 
    ROW_NUMBER() OVER (PARTITION BY EmpFirstName, EmpLastName ORDER BY ID) AS RowNum, 
    COUNT(*) OVER (PARTITION BY EmpFirstName, EmpLastName) AS cnt 
    FROM aTable 
) 
SELECT * FROM a where cnt > 1 
ORDER BY EmpFirstName, EmpLastName 

테스트

ID   EmpFirstName EmpLastName RowNum    cnt 
----------- ------------ ----------- -------------------- ----------- 
2   A   B   1     2 
3   A   B   2     2 
5   B   C   1     2 
6   B   C   2     2 
+0

나는 논리 'COUNT (*) OVER (PARTITION BY EmpFirstName, EmpLastName) AS cnt'가 좋았지 만 작동하지 않았다 ..성에 관계없이 EmpFirstName을 계산하고있다. ( –

+0

나를 위해 일한다 :'drop table #tmp (2, 'A', '1', 'X', 'Y') (1, 'X', 'Y') 삽입 테이블 #tmp (ID int, EmpFirstName varchar B, C ') , (6,'B ') (3,'A ', B') (4, 'A', 'C') , 'C') 으로, 선택 ID, EmpFirstName, EmpLastName, ROW_NUMBER() OVER (PARTITION BY EmpFirstName, Emp ID BY 성 순서) EmpFirstName, EmpLastName BY ROWNUM AS, COUNT (*) OVER (PARTITION)는 FROM #tmp ) SELECT * FROM AS CNT 곳 CNT> 1' – cha

+0

좋아, 나는 것 같다 왜 생각 생각 EmpFirstName에 의해 세고 있다는 것은 결과 집합이 정렬되지 않았기 때문입니다.질의 끝에'ORDER BY EmpFirstName, EmpLastName'을 추가하면 올바른 결과를 얻을 수 있습니다 – cha

0

샘플 데이터를 생성하고이 쿼리를 사용합니다.

CREATE table #tmp (ID int , EmpFirstName varchar(10) , EmpLastName varchar(10) ,RowNum int) 
INSERT INTO #tmp VALUES 
    (1,'X','Y',1) 
    ,(2,'A','B',1) 
    ,(3,'A','B',2) 

SELECT ID,EmpFirstName,EmpLastName,RowNum 
FROM (
    SELECT * 
     ,ROW_NUMBER() OVER (ORDER BY ID) AS [NEWrownum] 
    FROM #tmp 
) q 
WHERE q.NEWrownum > 1 
0

이 시도,

DECLARE @Result TABLE (ID INT, EmpFirstName VARCHAR(10), EmpLastName VARCHAR(10), RowNum INT) 

INSERT INTO @Result 
VALUES 
    (1, 'X', 'Y', 1) 
    ,(2, 'A', 'B', 1) 
    ,(3, 'A', 'B', 2) 

SELECT r1.* 
FROM @Result r1 
INNER JOIN (SELECT *  -- get duplicate records 
      FROM @Result 
      WHERE RowNum = 2     
      ) as r2 ON r1.EmpFirstName = r2.EmpFirstName 
        AND r1.EmpLastName = r2.EmpLastName