2013-07-31 4 views
5

여기에서 question을 따라 MySQL 쿼리를 사용하여 행을 열로 동적으로 변환했습니다. 이 잘 작동하지만 두 개의 열을 기준으로이 변환해야합니다두 열을 기준으로 행을 열로 동적으로 변환하는 MySQL 쿼리

위의 링크에서 언급 한 쿼리는 "데이터"단일 열에 대해 작동하지만 "데이터"및 " 가격".

Result Table 

| id|order1|order2|order3|item1|item2|item3|item4| 
-----+-----+--------------------------------------- 
| 1| P | Q |  | 50 | 60 | 70 |  | 
| 2| P |  | S | 50 | 60 |  | 80 | 

I : 나는 다음과 같은 쿼리를 작성하려

Table A 

| id|order|data|item|Price| 
-----+-----+---------------- 
| 1| 1| P| 1 | 50 | 
| 1| 1| P| 2 | 60 | 
| 1| 1| P| 3 | 70 | 
| 1| 2| Q| 1 | 50 | 
| 1| 2| Q| 2 | 60 | 
| 1| 2| Q| 3 | 70 | 
| 2| 1| P| 1 | 50 | 
| 2| 1| P| 2 | 60 | 
| 2| 1| P| 4 | 80 | 
| 2| 3| S| 1 | 50 | 
| 2| 3| S| 2 | 60 | 
| 2| 3| S| 4 | 80 | 

과 같이 테이블 A, 주어 내가 여기에 예를 추가 한

,

이를 달성하기 위해 두 개의 다른 쿼리를 만든 다음 조인을 시도했지만 좋은 해결책은 아닙니다. 위의 링크에서 언급 한 것과 같은 솔루션을 제안 할 수 있습니까?

감사

답변

15

당신이 orderitem 두 값의 알려진 숫자를 가지고 있다면, 당신은 하드에 쿼리를 코딩 할 수 있습니다 :

select id, 
    max(case when `order` = 1 then data end) order1, 
    max(case when `order` = 2 then data end) order2, 
    max(case when `order` = 3 then data end) order3, 
    max(case when item = 1 then price end) item1, 
    max(case when item = 2 then price end) item2, 
    max(case when item = 3 then price end) item3, 
    max(case when item = 4 then price end) item4 
from tableA 
group by id; 

Demo를 참조하십시오. 그러나 문제의 일부는 여러 데이터 열을 변환하려고하기 때문에 발생합니다. 최종 결과를 얻으려는 나의 제안은 데이터를 먼저 unpivot하는 것입니다. MySQL에는 unpivot 함수가 없지만 UNION ALL을 사용하여 여러 쌍의 열을 행으로 변환 할 수 있습니다. UNPIVOT에 대한 코드는 다음과 유사합니다

select id, concat('order', `order`) col, data value 
from tableA 
union all 
select id, concat('item', item) col, price value 
from tableA; 

Demo를 참조하십시오. 이것의 결과는 다음과 같습니다

| ID | COL | VALUE | 
----------------------- 
| 1 | order1 |  P | 
| 1 | order1 |  P | 
| 1 | order1 |  P | 
| 1 | item1 | 50 | 
| 1 | item2 | 60 | 
| 1 | item3 | 70 | 

이이 order/dataitem/price의 여러 열을 취한보고 여러 행으로 변환 할 수있다. 그이 완료되면, 당신은 CASE로 집계 함수를 사용하여 열을 다시 값을 변환 할 수 있습니다

select id, 
    max(case when col = 'order1' then value end) order1, 
    max(case when col = 'order2' then value end) order2, 
    max(case when col = 'order3' then value end) order3, 
    max(case when col = 'item1' then value end) item1, 
    max(case when col = 'item2' then value end) item2, 
    max(case when col = 'item3' then value end) item3 
from 
(
    select id, concat('order', `order`) col, data value 
    from tableA 
    union all 
    select id, concat('item', item) col, price value 
    from tableA 
) d 
group by id; 

Demo를 참조하십시오. 마지막으로, 당신은 동적 준비된 문 쿼리에 위의 코드를 변환 할 필요가 :

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when col = ''', 
     col, 
     ''' then value end) as `', 
     col, '`') 
) INTO @sql 
FROM 
(
    select concat('order', `order`) col 
    from tableA 
    union all 
    select concat('item', `item`) col 
    from tableA 
)d; 

SET @sql = CONCAT('SELECT id, ', @sql, ' 
        from 
        (
        select id, concat(''order'', `order`) col, data value 
        from tableA 
        union all 
        select id, concat(''item'', item) col, price value 
        from tableA 
       ) d 
        group by id'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

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

| ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 | ITEM3 | ITEM4 | 
------------------------------------------------------------------- 
| 1 |  P |  Q | (null) | 50 | 60 |  70 | (null) | 
| 2 |  P | (null) |  S | 50 | 60 | (null) |  80 | 
관련 문제