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

Разработка номер строки в подзапросе означает, что materia1 (например) всегда будет иметь значение (независимо от того, является ли оно сталью, золотом или серебром)

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]RN+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

Спасибо Salmon, это тоже работает правильно. – pietro