2012-09-27 25 views
4

我有產品零件的像這樣的表:MySQL的動態支點

part_id  part_type  product_id 
-------------------------------------- 
1   A    1 
2   B    1 
3   A    2 
4   B    2 
5   A    3 
6   B    3 

,我想查詢將返回一個表是這樣的:

product_id  part_A_id  part_B_id 
---------------------------------------- 
1    1    2 
2    3    4 
3    5    6 

在其實際實施中將會有數百萬的產品零件

+5

[你有什麼嘗試?](http://whathaveyoutried.com/) – ruakh

+3

你在找什麼通常被稱爲動態數據透視表。 –

+0

有幾種零件類型? – Lamak

回答

12

不幸的是,MySQL不具有PIVOT功能,但你可以使用聚合函數和CASE聲明建模。對於一個動態的版本,您將需要使用準備好的語句:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when part_type = ''', 
     part_type, 
     ''' then part_id end) AS part_', 
     part_type, '_id' 
    ) 
) INTO @sql 
FROM 
    parts; 
SET @sql = CONCAT('SELECT product_id, ', @sql, ' 
        FROM parts 
        GROUP BY product_id'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

SQL Fiddle With Demo

如果你只有幾列,那麼你可以使用一個靜態的版本:

select product_id, 
    max(case when part_type ='A' then part_id end) as Part_A_Id, 
    max(case when part_type ='B' then part_id end) as Part_B_Id 
from parts 
group by product_id 
+3

哇,你知道如何在我看到的每個關係數據庫上進行轉換 – Lamak

+0

謝謝,這可以完成這項工作。 SQL小提琴非常有幫助。 – Vaughan

+0

爲什麼max在這裏?是否因爲它需要在那裏具有聚合功能,它也可以是總和或其他東西? – Harlsten

-3

剛纔提到兩次 - (你真的沒有在這裏多了一個問題)

select a.product_id, a.part_id "part_a_id", b.part_id "part_b_id" 
from parts a, parts b 
where a.product_id = b.product_id 
+0

我想你誤解了這個問題。你應該回去重新審視他的例子。 – ajon

+0

我認爲這產生了所要求的結果。問題是可憐的艾莫。 – Randy

+0

除非我誤會,否則會產生不屬於他的結果的其他結果。例如:它會產生一行(1,1,1)以及(1,1,2)以及(1,2,1)以及(1,2,2)。 – ajon

1

SQL服務器有一個PIVOT關鍵字,但對於MySQL,您需要使用大量的CASE/IF語句或大量的JOIN。

Here是以前的文章如何做到這一點。