看起来您想将数据从单列、多行转换为多列和每人一行。这基本上是一个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 Fiddle
但是,如果您有未知数量的值,那么您可以使用准备好的语句来生成它的动态版本:
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 Fiddle
结果将与两者相同:
| K | OWNER | CARBRAND1 | CARBRAND2 | CARBRAND3 |
--------------------------------------------------
| 1 | Fred | VW | Honda | Mitsubishi |
| 2 | Jason | Toyota | (null) | (null) |
| 3 | Tonya | Ford | (null) | (null) |