看起来您希望将数据从单列,多行转换为每列多列和一行。这基本上是一个PIVOT
,但不幸的是MySQL没有PIVOT
函数,因此您需要使用具有CASE
语句的聚合函数来复制此函数。
如果你知道你要多少carbrands有你可以硬编码值,与此类似:
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:[email protected]+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 with Demo
但是,如果你有一个未知数量的值,那么你可以使用准备好的语句来生成的这个动态的版本:
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:[email protected]+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:[email protected]+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 with Demo
结果将是两者相同的:
| K | OWNER | CARBRAND1 | CARBRAND2 | CARBRAND3 |
--------------------------------------------------
| 1 | Fred | VW | Honda | Mitsubishi |
| 2 | Jason | Toyota | (null) | (null) |
| 3 | Tonya | Ford | (null) | (null) |
你给了我一个不错的主意。谢谢! – Rhyuk