2013-08-07 2 views
1

일부 비즈니스 응용 프로그램에서는 원시 데이터가 들어 와서 정규화 및 처리 한 다음보고 용도로 저장합니다. 예를 들어행을 열로 바꾸는 쿼리

, 원시 데이터 :

Transaction (transaction ID, employee 1 ID, employee 2 ID, employee 3 ID)

요구 사항보고에

TransactionEmployee (transaction ID, employee ID)

온다

Transaction(transaction ID)으로 정규화, 직원은 한 행에 표시해야 - 예 : TransactionReport(transaction ID, some details, employee 1 ID, employee 2 ID, employee 3 ID)

내 솔루션은 응용 프로그램 프로그래밍 언어를 사용하여 TransactionEmployee를 반복하고 INSERT 문을 작성하여보고 데이터를 다른 테이블 (3 개의 직원 ID가있는 각 트랜잭션)에 넣는 것입니다.

하지만 SQL에서 더 편하게 느낄 것입니다.

SQL을 통해 실현할 수 있습니까?

+2

Google 검색 문자열은 "MySQL의 피벗 쿼리"를 참조하십시오. 그건 그렇고, 거래가 3 명 이상의 직원을 가질 수 있습니까? –

+0

@DanBracuk 감사합니다. 거래에는 3 명 이상의 관련 직원이 없습니다. 피벗 쿼리에 대해 들었지만 'select limit 1'을 선택하고 'select limit 1 skip 1'을 선택한 다음 'select limit 1 skip 2'을 수행하는 것이 이상합니다. 더 나은 옵션이 있는지 궁금하십니까? –

답변

0

이렇게 할 수있는 한 가지 방법은 사용자 정의 변수를 사용하여 트랜잭션 당 각 직원의 행 번호를 생성 한 다음 CASE 식을 사용하여 집계 함수를 적용하여 데이터 행을 열로 변환 할 수 있습니다.

select transactionid, 
    max(case when row = 1 then employeeid end) employee1, 
    max(case when row = 2 then employeeid end) employee2, 
    max(case when row = 3 then employeeid end) employee3 
from 
(
    select t.transactionid, 
    e.employeeid, 
    @row:=case when @prev = t.transactionid then @row else 0 end +1 row, 
    @prev:=t.transactionid 
    from transaction t 
    left join transactionemployee e 
    on t.transactionid = e.transactionid 
    cross join (select @row:=0, @prev = 0) c 
    order by t.transactionid, e.employeeid 
) d 
group by transactionid 
order by transactionid; 

SQL Fiddle with Demo을 참조하십시오. 당신은 당신이 다음에 하위 쿼리와 유사한를 사용할 수있는 사용자 정의 된 변수를 사용하지 않을 경우

:

select transactionid, 
    max(case when row = 1 then employeeid end) employee1, 
    max(case when row = 2 then employeeid end) employee2, 
    max(case when row = 3 then employeeid end) employee3 
from 
(
    select t.transactionid, 
    e.employeeid, 
    (select count(*) 
    from transactionemployee te 
    where e.transactionid = te.transactionid 
     and te.employeeid <= e.employeeid) row 
    from transaction t 
    left join transactionemployee e 
    on t.transactionid = e.transactionid 
) d 
group by transactionid; 

SQL Fiddle with Demo