2012-11-15 66 views
1

我有两个关系一对多的表,可以说我有这个。将查询结果从一个查询转换为另一个列

**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 

我怎样才能做到这一点?

回答

2

不是真的,但这种接近

Select k, owner, group_concat(carbrand) 
FROM owners, cars 
WHERE 
owner.k = cars.k 
GROUP BY car brand 

很抱歉的格式,我会解决这个问题。

+0

你给了我一个不错的主意。谢谢! – Rhyuk

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:[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) | 
+0

随着你的内部连接和@Nils响应,我能解决我的问题。谢谢! – Rhyuk

相关问题