将垂直表转换为水平表

时间:2018-07-24 04:03:06

标签: mysql group-by case

我正在寻找一种干净,快速且不错的解决方案。 首先,我有一个看起来像这样的表

field_id   -    item_id   -   value
   1        -     781  -       name1
   2        -     781   -      lastname1
   3        -     781   -      phone1
   1        -     782   -      name2
   2        -     782   -      lastname2
   3        -     782   -      phone2
   1        -     783   -      name3
   2        -     783   -      lastname3
   3        -     783   -      phone3

我要这样显示此表:

item_id    -    name   -   lastname   -   phone
781     -        name1    -  lastname1   -   phone1
782     -        name2    -  lastname2   -   phone2   
783     -        name3    -  lastname3   -   phone3

我尝试过

SELECT field_id, item_id,
(CASE WHEN field_id = 1 THEN value END) AS name,
(CASE WHEN field_id = 2 THEN value END) AS lastname,
(CASE WHEN field_id = 3 THEN value END) AS phone
FROM cq6xb_fields_values
GROUP BY item_id;

但是我得到这个奇怪的结果

item_id    -    name   -   lastname   -   null 
781     -        null -  lastname1   -   null 
782     -        null -  lastname2   -   null 
783     -        null -  lastname3   -   null 

2 个答案:

答案 0 :(得分:1)

距离不远,只需添加max,就可以删除字段ID,因为您没有使用它。

SELECT item_id,
max(CASE WHEN field_id = 1 THEN value END) AS name,
max(CASE WHEN field_id = 2 THEN value END) AS lastname,
max(CASE WHEN field_id = 3 THEN value END) AS phone
FROM cq6xb_fields_values
GROUP BY item_id;

+---------+-------+-----------+--------+
| item_id | name  | lastname  | phone  |
+---------+-------+-----------+--------+
|     781 | name1 | lastname1 | phone1 |
|     782 | name2 | lastname2 | phone2 |
|     783 | name3 | lastname3 | phone3 |
+---------+-------+-----------+--------+
3 rows in set (0.00 sec)

答案 1 :(得分:0)

注意:看到我在您的问题下的评论,表结构本质上是不好的,这就是为什么它如此复杂的原因。

如果您确实希望通过这种方式,则需要连接到限于所属的field_id值的表,或者使用子查询。

所以这可以工作:

SELECT main.item_id, names.value AS name, lastnames.value AS lastname, phones.value AS phone
FROM cq6xb_fields_values AS main
    LEFT JOIN cq6xb_fields_values AS names ON names.item_id = main.item_id AND names.field_id=1
    LEFT JOIN cq6xb_fields_values AS lastnames ON lastnames.item_id = main.item_id AND lastnames.field_id=2
    LEFT JOIN cq6xb_fields_values AS phones ON phones.item_id = main.item_id AND phones.field_id=3
GROUP BY main.item_id