Mysql 将一个查询的查询结果转换为另一个查询的列
我有两个一对多的表,假设我有这个Mysql 将一个查询的查询结果转换为另一个查询的列,mysql,sql,join,pivot,Mysql,Sql,Join,Pivot,我有两个一对多的表,假设我有这个 **Table Owners** K Owner 1 Fred 2 Jason 3 Tonya 及 而不是得到这个: K Owner CarBrand 1 Fred Mitsubishi 1 Fred Honda 1 Fred VW 我想用这样的结果进行查询: K Owner CarBrand1 CarBrand2 Carbrand3 1 Fred Mitsubishi Honda VW 我怎样才能做到这一点呢?不太可能,但这很
**Table Owners**
K Owner
1 Fred
2 Jason
3 Tonya
及
而不是得到这个:
K Owner CarBrand
1 Fred Mitsubishi
1 Fred Honda
1 Fred VW
我想用这样的结果进行查询:
K Owner CarBrand1 CarBrand2 Carbrand3
1 Fred Mitsubishi Honda VW
我怎样才能做到这一点呢?不太可能,但这很接近
Select k, owner, group_concat(carbrand)
FROM owners, cars
WHERE
owner.k = cars.k
GROUP BY car brand
很抱歉设置了格式,我会解决的。不太好,但这很接近
Select k, owner, group_concat(carbrand)
FROM owners, cars
WHERE
owner.k = cars.k
GROUP BY car brand
很抱歉设置了格式,我会解决这个问题。看起来您希望将数据从单列、多行转换为多列,每人一行。这基本上是一个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
看
但是,如果您有未知数量的值,则可以使用准备好的语句生成此值的动态版本:
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) |
看起来您希望将数据从单列、多行转换为多列和每人一行。这基本上是一个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
看
但是,如果您有未知数量的值,则可以使用准备好的语句生成此值的动态版本:
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) |
你给了我一个好主意。谢谢你给了我一个好主意。谢谢通过您的内部连接和@Nils响应,我能够解决我的问题。谢谢通过您的内部连接和@Nils响应,我能够解决我的问题。谢谢