ここでは 質問 に従って、Mysqlクエリを使用して行を列に動的に変換しました。これは正常に機能しますが、2つの列に基づいてこれを変換する必要があります。
上記のリンクで言及されているクエリは、単一の列「data」に対して機能しますが、「data」と「price」の2つの列に対して機能したいと思います。
ここに例を追加しました、
次のようなテーブル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 |
これを実現するために、2つの異なるクエリを作成してから結合を作成しようとしましたが、それは適切な解決策ではない可能性があります。上記のリンクで述べたのと同じ解決策を誰かが提案できますか?.
ありがとう
order
とitem
の両方に既知の数の値がある場合は、クエリを次のようにハードコーディングできます。
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にはピボット解除機能はありませんが、UNION ALLを使用して、列の複数のペアを行に変換できます。ピボットを解除するコードは次のようになります。
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 |
ご覧のとおり、これはorder
/data
とitem
/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;
デモ を参照してください。最後に、上記のコードを動的なプリペアドステートメントクエリに変換する必要があります。
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 |