2012-05-07 3 views
32

다른 사람이 작성한 SQL 쿼리가 있는데 어떻게 처리되는지 알아 내려고합니다. 누군가 Partition ByRow_Number 키워드가 여기에서 무엇을하는지 설명하고 간단한 예를 제시 할 수 있습니까? 왜 그것을 사용하고 싶은지?오라클의 'Partition By'와 'Row_Number'키워드

하여 파티션의 예 : 나는 온라인으로 몇 가지 예를 본 적이

(SELECT cdt.*, 
     ROW_NUMBER() 
     OVER (PARTITION BY cdt.country_code, cdt.account, cdt.currency 
       ORDER BY cdt.country_code, cdt.account, cdt.currency) 
      seq_no 
    FROM CUSTOMER_DETAILS cdt); 

, 그들은 조금 너무 깊이에 있습니다.

미리 감사드립니다.

답변

89

PARTITION BY 분리 세트,이 독립적으로 관련 세트 (ROW_NUMBER(), COUNT(), SUM() 등)이 작동 할 수 있습니다.

관련 검색어는 cdt.country_code, cdt.account, cdt.currency와 비슷한 행으로 구성됩니다. 해당 열을 분할하고 ROW_NUMBER를 적용하면 해당 조합/세트의 다른 열은 ROW_NUMBER에서 일련 번호를받습니다.

하지만 고유 한 데이터로 파티션을 만들고 row_number를두면 동일한 숫자가됩니다. 고유 한 것으로 보장 된 파티션에서 ORDER BY를 수행하는 것과 같습니다. 예를 들어, GUID를 고유 한 조합으로 생각하면 cdt.country_code, cdt.account, cdt.currency

이 GUID를 생성하므로이 표현에서 무엇을 기대할 수 있습니까?

select 
    hi,ho, 
    row_number() over(partition by newid() order by hi,ho) 
from tbl; 

... 오른쪽, 모든이 아닌 고유에 분할해야 행 'row_numbers 모두 기본적으로 1

로 설정 (없음은, 모든 행이 자신의 행에 분할되어 분할되지 않은) 분할 열. 그런 다음이 쿼리와 유사

create table tbl(hi varchar, ho varchar); 

insert into tbl values 
('A','X'), 
('A','Y'), 
('A','Z'), 
('B','W'), 
('B','W'), 
('C','L'), 
('C','L'); 

: OVER에서 ORDER BY 그렇지 않으면 모든 row_numbers 1

예를 될 것입니다, 고유하지 않은 조합을 위해 파티션 BY 필요, 데이타입니다

select 
    hi,ho, 
    row_number() over(partition by hi,ho order by hi,ho) 
from tbl; 

출력은 어떻게됩니까?

HI HO COLUMN_2 
A X 1 
A Y 1 
A Z 1 
B W 1 
B W 2 
C L 1 
C L 2 

당신은 HI HO의 조합을 보았습니까? 처음 세 행은 고유 한 조합을 가지므로 1로 설정되고 B 행은 동일한 W를 가지므로 HI C 행과 마찬가지로 다른 ROW_NUMBERS를가집니다.

이제는 ORDER BY이 필요한 이유는 무엇입니까?

select 
    hi,ho, 
    row_number() over(partition by hi,ho) 
from tbl; 

을하지만 슬프게도, 오라클은 (및 SQL Server도) 아무튼 : 이전 개발자가 단순히 유사한 데이터에 ROW_NUMBER 넣어하려는 경우 (예 : HI B를, 모든 데이터가 BW, BW이다), 그는 단지 이렇게 할 수 있습니다 파티션을 허용하지 않고 ORDER BY; PostgreSQL을에, 파티션에 ORDER BY는 선택 사항입니다 반면 : http://www.sqlfiddle.com/#!1/27821/1

select 
    hi,ho, 
    row_number() over(partition by hi,ho) 
from tbl; 

귀하의 파티션에 ORDER BY이 때문이 아니라 이전 개발자의 잘못의 중복 좀 봐, 일부 데이터베이스는 단지 더 ORDER BYPARTITION을 허용하지 않는, 그는 수도 정렬 할 수있는 후보 열을 찾을 수 없습니다. 열 BY 열 및 ORDER BY 모두 파티션이 같은 경우 단지 ORDER BY를 제거 할 수 있지만 일부 데이터베이스는 그것을 허용하지 않기 때문에, 당신은이 수행 할 수

SELECT cdt.*, 
     ROW_NUMBER() 
     OVER (PARTITION BY cdt.country_code, cdt.account, cdt.currency 
       ORDER BY newid()) 
      seq_no 
    FROM CUSTOMER_DETAILS cdt 

당신이 사용하는 것이 열을 찾을 수 없습니다 유사한 데이터 정렬? 무작위로 정렬 할 수도 있지만 분할 된 데이터의 값은입니다. 예를 들어 GUID를 사용할 수 있습니다 (SQL Server의 경우 newid()을 사용합니다). 그래서 이전 개발자가 만든 동일한 출력을 가지고 있습니다. 일부 데이터베이스에서는 허용되지 않는 것이 유감입니다. ORDER BY

실제적으로 그것은 나를 피하고 동일한 조합에 숫자를 넣을 좋은 이유를 찾을 수 없습니다. BW, BW 위의 예제). 그것은 중복 데이터를 갖는 데이터베이스의 인상을주고 있습니다. 어떻게 든 나에게 이것을 상기 시켰습니다 : How to get one unique record from the same list of records from table? No Unique constraint in the table

ORDER BY와 같은 열의 조합으로 PARTITION BY를 보았을 때 실제로 코드의 의도를 쉽게 추측 할 수 없었습니다.

라이브 테스트 :


그러나 dbaseman로 http://www.sqlfiddle.com/#!3/27821/6도 나타났습니다, 그것은 분할하고 위해 같은 열에 쓸모입니다.

당신은이 같은 데이터 세트를 가지고 :

create table tbl(hi varchar, ho varchar); 

insert into tbl values 
('A','X'), 
('A','X'), 
('A','X'), 
('B','Y'), 
('B','Y'), 
('C','Z'), 
('C','Z'); 

그런 다음 BY 파티션 호, 안녕하세요; 안녕하세요, 호.

HI HO ROW_QUERY_A 
A X 1 
A X 2 
A X 3 
B Y 1 
B Y 2 
C Z 1 
C Z 2 

참조 : http://www.sqlfiddle.com/#!3/29ab8/3

select 
    hi,ho, 
    row_number() over(partition by hi,ho order by hi,ho) as nr 
from tbl; 

출력 :-) 유사한 데이터를 번호 아무 의미가 없습니다? 동일한 조합에 행 번호를 입력해야하는 이유는 무엇입니까? 당신은 트리플 A, X, 더블 B, Y, 더블 C, Z에서 무엇을 분석할까요? :-)


당신은 다음 종류의 고유하지 않은 컬럼 (들)의 독특한 -ing 열, 고유하지 않은 컬럼에 파티션을 사용해야합니다.예 좀 더 명확하게됩니다

create table tbl(hi varchar, ho varchar); 

insert into tbl values 
('A','D'), 
('A','E'), 
('A','F'), 
('B','F'), 
('B','E'), 
('C','E'), 
('C','D'); 

select 
    hi,ho, 
    row_number() over(partition by hi order by ho) as nr 
from tbl; 

PARTITION BY hi 당신은 그것의 고유 한 열 (호)에 주문, 각 분할 열이 아닌 고유 한 컬럼에서 작동 ORDER BY ho

출력 :

HI HO NR 
A D 1 
A E 2 
A F 3 
B E 1 
B F 2 
C D 1 
C E 2 
http://www.sqlfiddle.com/#!3/d0b44/1

:

이 데이터 세트는 더 의미를

라이브 테스트한다 691,363,210

그리고 이것은 BY 모두 BY 파티션 및 ORDER에 같은 열이 쿼리와 유사하다 :

select 
    hi,ho, 
    row_number() over(partition by hi,ho order by hi,ho) as nr 
from tbl; 

그리고 이것은 OUPUT입니다 :

HI HO NR 
A D 1 
A E 1 
A F 1 
B E 1 
B F 1 
C D 1 
C E 1 

보기? 말이되지 않는다?

라이브 테스트 : http://www.sqlfiddle.com/#!3/d0b44/3


마지막으로이 오른쪽 쿼리 수 있습니다 :

SELECT cdt.*, 
    ROW_NUMBER() 
    OVER (PARTITION BY cdt.country_code, cdt.account -- removed: cdt.currency 
      ORDER BY 
       -- removed: cdt.country_code, cdt.account, 
       cdt.currency) -- keep 
     seq_no 
FROM CUSTOMER_DETAILS cdt 
7

국가 코드, 계정 및 통화별로 행 번호가 선택됩니다. 따라서 국가 코드 "US", 계정 "XYZ"및 통화 "$ USD"가있는 행은 각각 1-n에서 할당 된 행 번호를 얻습니다. 결과 집합의 해당 열을 다른 모든 조합에 대해 동일하게 적용됩니다.

에 의한 주문의 순서는 전혀 없습니다.이 쿼리는 다소 재미 있습니다. 각 파티션의 모든 행은 동일한 국가 코드, 계정 및 통화를 가지므로 해당 열의 순서가 없습니다. 따라서이 특정 쿼리에 할당 된 최종 행 번호는 예측할 수 없습니다. 도움이

희망 ...

4

나는 종종 내 SELECT 문에서 중복 레코드를 삭제하는 빠른 방법으로 ROW_NUMBER()를 사용합니다. where 절을 추가하십시오. 뭔가 같은 ...

select a,b,rn 
    from (select a, b, row_number() over (partition by a,b order by a,b) as rn   
      from table) 
where rn=1; 
2

나는이 오래된 쓰레드지만 파티션 BY 주문하지 BY GROUP의 당량 알고있다. 이 함수의 ORDER BY는입니다. . . 주문. 이는 순차 번호를 추가하여 중복성에서 독창성을 창출하는 방법 일뿐입니다. 또는 함수의 별칭이 지정된 열을 참조 할 때 WHERE 절에 의해 다른 중복 레코드를 제거 할 수 있습니다. 그러나 SELECT 문에서 DISTINCT는 아마도 이와 관련하여 동일한 결과를 얻을 수 있습니다.

관련 문제