2012-11-15 64 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

相關問題