복붙노트

[SQL] 두 개의 열을 기준으로 열을 동적으로 변환 행에 MySQL의 쿼리

SQL

두 개의 열을 기준으로 열을 동적으로 변환 행에 MySQL의 쿼리

동적으로 컬럼에 행을 변환하는 MySQL의 쿼리를 사용하여 여기에 질문을 따랐다. 이 잘 작동,하지만 난 두 개의 컬럼의 기준이 변환해야,

위의 링크에서 언급 된 쿼리는 단일 컬럼에 대해 "데이터"작동하지만, 난 "데이터"와 "가격"두 컬럼에 대한 작업을 할 수 있습니다.

난 다음 예를 추가 한

같이 테이블 A를 감안할 때

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  |

나는 쿼리를 작성하고자 그 다음과 같습니다 :

Result Table

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

나는 두 개의 서로 다른 쿼리를 만들려고 한 후,이를 달성하기 위해 가입,하지만 좋은 솔루션이 될 수 없습니다. 하나는 위의 링크에서 언급처럼 같은 솔루션을 제안 할 수 있습니다.

감사

해결법

  1. ==============================

    1.당신은 순서 및 항목 모두에 대한 값의 알려진 수, 당신은 할 수 하드 코드 쿼리에 있던 경우 :

    당신은 순서 및 항목 모두에 대한 값의 알려진 수, 당신은 할 수 하드 코드 쿼리에 있던 경우 :

    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;
    

    데모를 참조하십시오. 당신은 데이터의 여러 열을 변환하려고하기 때문에 그러나 당신이하려고하는 문제의 일부입니다. 최종 결과를 얻기 위해 나의 제안은 먼저 데이터를 피벗 해제하는 것입니다. 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;
    

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

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

    이 순서 / 데이터 및 아이템 / 가격의 여러 열을 취한보고 여러 행으로 변환 할 수있다. 그이 완료되면, 당신은 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;
    

    데모를 참조하십시오. 마지막으로, 당신은 동적 준비된 문 쿼리에 위의 코드를 변환해야합니다 :

    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 바이올린을 참조하십시오. 이 결과를 제공합니다 :

    | ID | ORDER1 | ORDER2 | ORDER3 | ITEM1 | ITEM2 |  ITEM3 |  ITEM4 |
    -------------------------------------------------------------------
    |  1 |      P |      Q | (null) |    50 |    60 |     70 | (null) |
    |  2 |      P | (null) |      S |    50 |    60 | (null) |     80 |
    
  2. from https://stackoverflow.com/questions/17964078/mysql-query-to-dynamically-convert-rows-to-columns-on-the-basis-of-two-columns by cc-by-sa and MIT license