sql >> Databáze >  >> RDS >> Mysql

Mysql dotaz pro dynamickou konverzi řádků na sloupce na základě dvou sloupců

Pokud jste měli známý počet hodnot pro obě order a item , pak byste mohli natvrdo zakódovat dotaz do:

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;

Viz Ukázka . Ale součástí problému, který budete mít, je to, že se pokoušíte transformovat více sloupců dat. Můj návrh, jak získat konečný výsledek, by bylo nejprve odklopit data. MySQL nemá funkci unpivot, ale můžete použít UNION ALL pro převod několika párů sloupců na řádky. Kód pro unpivot bude podobný následujícímu:

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

Viz Ukázka . Výsledkem bude:

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

Jak můžete vidět, zabralo to několik sloupců order /data a item /price a převést jej do více řádků. Po dokončení můžete hodnoty převést zpět na sloupce pomocí agregační funkce s 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;

Viz Ukázka . Nakonec je třeba převést výše uvedený kód na dynamicky připravený příkazový dotaz:

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;

Viz SQL Fiddle s ukázkou . Výsledkem je:

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



  1. Dotaz MySQL Insert nefunguje s klauzulí WHERE

  2. Aktualizace SQLite

  3. Kolik uživatelů má přístup k podpoře?

  4. SQLite levé připojení