2016-10-01 38 views
1

我堅持這條SQL問題:SQL合併行轉換成列(多對多情況)

DB:MySQL的5.6.15 存儲引擎:MyISAM的

我有3個表:

1)產品

id product | product_name  
---------- | --------------  
1   | alfa  
2   | beta  
3   | gamma 

2)products_materials [這是橋接表]

id product | id material  
---------- | --------------  
1   | 1  
1   | 2  
1   | 3 
2   | 1 
3   | 1 

3)材料

id material| material_name 
---------- | -------------- 
1   | steel 
2   | gold  
3   | silver 

我需要獲得這樣的結果:

id product | material_name_1 | material_name_2 | material_name_3  
------------|--------------------|-------------------|--------------------  
product 1  steel     gold    silver  
product 2  gold     null    null  
product 3  silver     null    null  

每個產品的最大的材料是10 我當時一看轉動,但我不夠自信用它來創建正確的查詢。

非常感謝

+0

總共有10種不同的材料嗎? – Jayvee

回答

0

如果有10種固定的產品,那麼你可以做這樣的事情:

select p.product_name, 

(select m.material_name 
from products p1 
join products_materials pm on pm.id_product=p1.id 
join materials m on m.id=pm.id_material 
where m.id=1 
and p1.id=p.id) as material1, 

(select m.material_name 
from products p1 
join products_materials pm on pm.id_product=p1.id 
join materials m on m.id=pm.id_material 
where m.id=2 
and p1.id=p.id) as material2, 

(select m.material_name 
from products p1 
join products_materials pm on pm.id_product=p1.id 
join materials m on m.id=pm.id_material 
where m.id=3 
and p1.id=p.id) as material3 

from products p 

(本例中是3個可能的產品)

+0

謝謝Jayvee,這是一個工作解決方案 – pietro

0

工作了行號在子查詢中意味着材料1(例如)將始終具有值(不論它是鋼,金還是銀)

SELECT S.PRODUCT_NAME, 
     MAX(CASE WHEN RN=1 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL1, 
     MAX(CASE WHEN RN=2 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL2, 
     MAX(CASE WHEN RN=3 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL3, 
     MAX(CASE WHEN RN=4 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL4, 
     MAX(CASE WHEN RN=5 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL5, 
     MAX(CASE WHEN RN=6 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL6, 
     MAX(CASE WHEN RN=7 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL7, 
     MAX(CASE WHEN RN=8 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL8, 
     MAX(CASE WHEN RN=9 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL9, 
     MAX(CASE WHEN RN=10 THEN S.MATERIAL_NAME ELSE '' END) MATERIAL10 
FROM 
(
SELECT P.PRODUCT_NAME,.M.MATERIAL_NAME, 
     IF(P.ID <> @P,@RN:=1,@RN:[email protected]+1) RN, 
     @P:=P.ID P 
FROM (SELECT @RN:=0,@P:=0) RN,PRODUCTS P 
JOIN PRODUCTS_MATERIALS PM ON PM.PRODUCT_ID = P.ID 
JOIN MATERIALS M ON M.MATERIAL_ID = PM.MATERIAL_ID 
) S 
GROUP BY S.PRODUCT_NAME 
ORDER BY S.PRODUCT_NAME 
+0

謝謝三文魚,這也正常工作。 – pietro