具有逗号的多个值的列

时间:2015-04-24 11:04:12

标签: mysql sql

有3个表,如下所示

表:prod p

+-----+--------------+
|codes|desc          |
+-----+--------------+
|100  |table 1       |
|101  |chair 1       |
|102  |chair 2       |
+-----+--------------+

表:prod_details d

+-----+--------------+
|codes|mat_id        |
+-----+--------------+
|100  |50,52         |
|101  |53            |
|102  |51,52,54      |
+-----+--------------+

表:材料

+------+-------------+
|mat_id|mat_name     |
+------+-------------+
|50    |pine wood    |
|51    |acacia wood  |
|52    |MDF          |
|53    |stainless s  |
|54    |leather      | 
+------+-------------+

我想要一个这样的结果:

+-----+-----------+------------------------+
|code |mat_id     |mat_name                |
+-----+-----------+------------------------+
|100  |50,52      |pine wood,MDF           |
|101  |53         |stainless s             |
|102  |51,52,54   |acacia wood,MDF,leather |
+-----+-----------+------------------------+

然而,材料名称仅显示一个,如下所示:

+-----+-----------+------------------------+
|code |mat_id     |mat_name                |
+-----+-----------+------------------------+
|100  |50,52      |pine wood               |
|101  |53         |stainless s             |
|102  |51,52,54   |acacia wood             |
+-----+-----------+------------------------+

我正在使用以下查询,但显然无效。

SELECT p.codes, d.mat_id, 
(SELECT group_concat(mat_name separator',') FROM materials WHERE mat_id IN (d.mat_id))
FROM prod p
LEFT JOIN prod_details d on (p.codes=d.codes)
GROUP BY p.codes

我知道桌子的设计很糟糕但是我无法改变它。 此外,我无法在情况下使用php,因此只需要按mysql排序。

如果有人可以帮助我,那将是感激的。 提前谢谢。

2 个答案:

答案 0 :(得分:4)

你似乎知道你的设计非常糟糕。你应该努力修复它,并记住两件事:(1)永远不要将列表存储在分隔的字符串中。 (2)不要在字符字段中存储数字id。

也就是说,你可以通过相当痛苦的查询得到你想要的东西:

select pd.*,
       group_concat(m.mat_name) as mat_names
from prod_details pd left join
     materials m
     on find_in_set(m.mat_id, p.mat_id) > 0
group by pd.codes;

注意:无法保证名称与ids的顺序相同。如果你想保证,重建id:

select pd.codes, group_concat(m.mat_id order by m.mat_id) as mat_ids,
       group_concat(m.mat_name order by m.mat_id) as mat_names
from prod_details pd left join
     materials m
     on find_in_set(m.mat_id, p.mat_id) > 0
group by pd.codes;

答案 1 :(得分:1)

试试这个

select distinct t.codes,t.id1,
STUFF((SELECT ',' + mtr.mat_name FROM material  mtr WHERE  t.id1  like '%'+CONVERT(varchar(10),mtr.mat_id)+'%'
FOR XML PATH('')),1,1,'') 
 from 
(select pd.codes,pd.mat_id as id1,m.mat_id as id2,m.mat_name from prod_details pd inner join material m on  pd.mat_id like '%'+CONVERT(varchar(10),m.mat_id)+'%')
as t