2013-12-16 2 views
1

없이 나는이 데이터를 다음 표 (?)피벗 알려진 열 이름

이제
A B 
=== === 
M 2 
M 3 
M 5 
N 5 
N 2 
O 6 
P 13 
P 7 
P 9 
P 11 
P 3 

나는 PIVOT 필요 질의 : 열 A에 의해

  • 그룹
  • 정렬에 열 B
  • B 열에서 가장 낮은 값을 사용하십시오.
  • 이 값을 새 열 B1, B2, B3에 넣으십시오.

그래서 결과는 다음과 같습니다

A B1 B2 B3 
=== ==== ==== ==== 
M 2 3 5 
N 2 5 null 
O 6 null null 
P 3 7 9 

지금까지 내가 TOP와 쿼리, GROUP BY, PIVOT을 만들려고하고 있습니다. 가장 좋은 방법은 PIVOT을 사용하는 것입니다. 그러나 열 이름으로 사용할 수있는 값이 없기 때문에 저는 붙어 있습니다. 또한, 이러한 값 중 상위 3 개를 선택하는 것도 상당히 어려운 일입니다.

* EDIT *

그들의 열 A와 B의 고유 제약, 그래서 B의 값이 항상 동일한 A. 여기

+0

어떤 데이터베이스를 사용하고 있습니까? Oracle 또는 SQL Server? –

+0

오라클을 사용하고 있습니다. 잘못된 태그를 제거했습니다. –

+1

@MartinMulder 어떤 오라클 버전을 사용하고 있습니까? – Taryn

답변

4

에 대한 고유은 모두 오라클과 작동하는 방법이다 및 SQL Server (원래 질문에 두 데이터베이스로 태그가 지정되었습니다).

당신은 (중복이있는 경우 세 가지 다른 값을 줄 것이다 또는 row_number()하지만 dense_rank()) 각 dense_rank()를 사용 a에 대한 b 값을 열거 할 수 있습니다. 그런 다음 피벗 조건부 집계를 사용하여 :

with ab as (
     select a, b, 
      dense_rank() over (partition by a order by b asc) as seqnum 
     from t 
    ) 
select a, 
     max(case when seqnum = 1 then b end) as b1, 
     max(case when seqnum = 2 then b end) as b2, 
     max(case when seqnum = 3 then b end) as b3 
from ab 
group by a; 

편집 :

문제는 중복이있는 경우 수행 할 작업에 대한 불분명합니다. 예를 들어, b의 데이터가 1, 1, 2, 3 인 경우 어느 것이 3 개의 열이되어야합니까?

1, 2, 3 

또는 1, 1, 2

dense_rank()의 사용은 열 (제 가능한 결과)으로 세 가지 서로 다른 값을 넣는다. row_number()을 사용하면 세 개의 가장 작은 값 (두 번째 결과)을 넣습니다. 중복 값이없는 경우 dense_rank()row_number()은 동일한 결과를 생성합니다.

+0

'DENSE_RANK'는 (적어도 SQL Server에서는) 그런 식으로 작동하지 않습니다. 중복되는 경우 동일한 값을 제공합니다. 반면에'ROW_NUMBER'는 당신이 원하는대로 동작합니다. – Lamak

+0

@Lamak. . . 중복이있는 경우'dense_rank()'가 'b'의 세 가지 다른 값을 제공한다는 의미였습니다. 'row_number()'는'b'의 값을 반복합니다. OP가 무엇을 원하는지 불분명합니다. –

+0

네, 그게 맞지 않아요. 'dense_rank'은 복제본의 경우 같은 값을 반환 할 것이고'row_number'는 @Lamak이 아닙니다. – Lamak

7

결과를 얻으려면 PIVOT 함수를 사용할 수 있지만 최종 결과를 얻으려면 row_number()과 유사한 창 함수를 구현할 수도 있습니다. A 열을 통해 데이터를 분할하면 row_number() 함수는 각 B 값에 고유 한 순차 번호를 만듭니다. 이 시퀀스 번호는 새 열 이름으로 사용됩니다.

select a, B1, B2, B3 
from 
(
    select a, b, 
    row_number() over(partition by a 
         order by b) seq 
    from yourtable 
) d 
pivot 
(
    max(b) 
    for seq in ('1' as B1, '2' as B2, '3' as B3) 
) piv; 

SQL Fiddle with Demo을 참조하십시오. 결과는 다음과 같습니다.

| A | B1 |  B2 |  B3 | 
|---|----|--------|--------| 
| M | 2 |  3 |  5 | 
| N | 2 |  5 | (null) | 
| O | 6 | (null) | (null) | 
| P | 3 |  7 |  9 |