Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapytanie Mysql do dynamicznej konwersji wierszy na kolumny na podstawie dwóch kolumn

Jeśli masz znaną liczbę wartości dla obu order i item , możesz na stałe zakodować zapytanie w:

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;

Zobacz Demo . Ale część problemu, który będziesz mieć, polega na tym, że próbujesz przekształcić wiele kolumn danych. Moja sugestia, aby uzyskać ostateczny wynik, to najpierw unpivotować dane. MySQL nie posiada funkcji unpivot, ale możesz użyć UNION ALL do konwersji wielu par kolumn na wiersze. Kod do unpivot będzie podobny do następującego:

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

Zobacz Demo . Rezultatem tego będzie:

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

Jak widać, zajęło to wiele kolumn order /data i item /price i przekonwertuj go na wiele wierszy. Po zakończeniu możesz przekonwertować wartości z powrotem na kolumny za pomocą funkcji agregującej ze znakiem 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;

Zobacz Demo . Na koniec musisz przekonwertować powyższy kod na dynamiczne zapytanie z przygotowanym zestawieniem:

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;

Zobacz SQL Fiddle z demonstracją . Daje to wynik:

| 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. JSON_VALID() – Testuj poprawność JSON w MySQL

  2. Jak naprawić nieprawidłową wartość ciągu w MySQL?

  3. Znajdź odległość między dwoma punktami za pomocą szerokości i długości geograficznej w mysql

  4. Zrozumienie MySQL TRUNCATE TABLE na praktycznych przykładach

  5. PHP PDOException:SQLSTATE[HY093]:Nieprawidłowy numer parametru