我有两张表与一对多的关系,让我说我有这个。
**Table Owners**
K Owner
1 Fred
2 Jason
3 Tonya
和
Table Cars
K CarBrand
1 Mitsubishi
1 Honda
1 VW
2 Toyota
3 Ford
而不是得到这个:
K Owner CarBrand
1 Fred Mitsubishi
1 Fred Honda
1 Fred VW
我想用这样的结果进行查询:
K Owner CarBrand1 CarBrand2 Carbrand3
1 Fred Mitsubishi Honda VW
我怎样才能做到这一点?
答案 0 :(得分:2)
不是真的,但这很接近
Select k, owner, group_concat(carbrand)
FROM owners, cars
WHERE
owner.k = cars.k
GROUP BY car brand
对不起格式化,我会解决这个问题。
答案 1 :(得分:2)
看起来您希望将数据从单列,多行转换为多列,每行一行。这基本上是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:=@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
但是,如果您有一个未知数量的值,那么您可以使用预准备语句生成此动态版本:
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;
两者的结果相同:
| K | OWNER | CARBRAND1 | CARBRAND2 | CARBRAND3 |
--------------------------------------------------
| 1 | Fred | VW | Honda | Mitsubishi |
| 2 | Jason | Toyota | (null) | (null) |
| 3 | Tonya | Ford | (null) | (null) |