データを単一の列、複数の行から複数の列、および1人あたり1つの行に変換したいようです。これは基本的にはですPIVOT
が、残念ながらMySQLには関数がないため、ステートメントPIVOT
を含む集計関数を使用してこれを複製する必要があります。CASE
所有するカーブランドの数がわかっている場合は、次のように値をハードコーディングできます。
select k, owner,
max(case when nameRn = 'CarBrand1' then carbrand end) CarBrand1,
max(case when nameRn = 'CarBrand2' then carbrand end) CarBrand2,
max(case when nameRn = 'CarBrand3' then carbrand end) CarBrand3
from
(
select k, owner, carbrand,
concat('CarBrand', @num := if(@owner = `owner`, @num + 1, 1)) as nameRn,
@owner := `owner` as dummy
from
(
select k, owner, carbrand, @rn:=@rn+1 overall_row_num
from
(
select o.k, o.owner, c.carbrand
from owners o
inner join cars c
on o.k = c.k
order by carbrand
) oc, (SELECT @rn:=0) r
order by k
) r
) src
group by k, owner
SQL FiddlewithDemoを参照してください
ただし、値の数が不明な場合は、プリペアドステートメントを使用して、次の動的バージョンを生成できます。
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when nameRn = ''',
nameRn,
''' then carbrand end) AS ',
nameRn
)
) INTO @sql
FROM
(
select k, owner, carbrand,
concat('CarBrand', @num := if(@owner = `owner`, @num + 1, 1)) as nameRn,
@owner := `owner` as dummy
from
(
select k, owner, carbrand, @rn:=@rn+1 overall_row_num
from
(
select o.k, o.owner, c.carbrand
from owners o
inner join cars c
on o.k = c.k
order by carbrand
) oc, (SELECT @rn:=0) r
order by k
) r
) src;
SET @sql = CONCAT('SELECT k, owner, ', @sql, '
from
(
select k, owner, carbrand,
concat(''CarBrand'', @num := if(@owner = `owner`, @num + 1, 1)) as nameRn,
@owner := `owner` as dummy
from
(
select k, owner, carbrand, @rn:=@rn+1 overall_row_num
from
(
select o.k, o.owner, c.carbrand
from owners o
inner join cars c
on o.k = c.k
order by carbrand
) oc, (SELECT @rn:=0) r
order by k
) r
) src
GROUP BY k, owner');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SQL FiddlewithDemoを参照してください
結果は両方で同じになります:
| K | OWNER | CARBRAND1 | CARBRAND2 | CARBRAND3 |
--------------------------------------------------
| 1 | Fred | VW | Honda | Mitsubishi |
| 2 | Jason | Toyota | (null) | (null) |
| 3 | Tonya | Ford | (null) | (null) |