2016-10-01 60 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