如何将键值对结构数据库表的查询结果转为多列格式?
解决方案:EAV表转宽表
没问题,这是典型的EAV(实体-属性-值)模型转宽表的场景,咱们用条件聚合就能轻松实现你的需求。
你的表结构
首先明确你的表结构(替换your_table_name为实际表名):
CREATE TABLE your_table_name ( id bigint(20) unsigned AUTO_INCREMENT, form_id mediumint(8) unsigned DEFAULT 0, entry_id bigint(20) unsigned, meta_key varchar(255) DEFAULT NULL, meta_value longtext DEFAULT NULL, PRIMARY KEY (id) );
当前数据(整理为Markdown表格)
| id | form_id | entry_id | meta_key | meta_value |
|---|---|---|---|---|
| 3 | 1 | 1 | 14 | Address 1 |
| 6 | 1 | 1 | 20 | 1 |
| 7 | 1 | 1 | 21 | 2018-16-05 |
| 8 | 1 | 1 | 23 | Product 1 |
| 11 | 1 | 2 | 14 | Address 2 |
| 14 | 1 | 2 | 20 | 1 |
| 15 | 1 | 2 | 21 | 2018-16-05 |
| 16 | 1 | 2 | 23 | Product2 |
| 20 | 1 | 3 | 14 | Address3 |
| 21 | 1 | 3 | 20 | 1 |
| 22 | 1 | 3 | 21 | 2018-16-05 |
| 23 | 1 | 3 | 23 | Prodcut3 |
实现需求的SQL语句
这条语句会把同一entry_id下不同meta_key对应的meta_value转换成单独的列:
SELECT entry_id, MAX(CASE WHEN meta_key = '14' THEN meta_value END) AS meta_value1, MAX(CASE WHEN meta_key = '20' THEN meta_value END) AS meta_value2, MAX(CASE WHEN meta_key = '21' THEN meta_value END) AS meta_value3, MAX(CASE WHEN meta_key = '23' THEN meta_value END) AS meta_value4 FROM your_table_name -- 如果只需要特定form_id的数据,可以加上下面的条件 -- WHERE form_id = 1 GROUP BY entry_id ORDER BY entry_id;
语句解释
CASE WHEN:判断每条记录的meta_key,匹配指定值时返回对应的meta_value,否则返回NULLMAX():因为同一entry_id+meta_key只会有一条记录,用MAX()(或MIN())聚合可以把同一entry_id下的不同属性值合并到一行GROUP BY entry_id:确保每个entry_id只生成一行结果ORDER BY entry_id:按条目ID排序,让结果更规整
查询结果
执行后会得到你想要的格式:
| entry_id | meta_value1 | meta_value2 | meta_value3 | meta_value4 |
|---|---|---|---|---|
| 1 | Address 1 | 1 | 2018-16-05 | Product 1 |
| 2 | Address 2 | 1 | 2018-16-05 | Product2 |
| 3 | Address3 | 1 | 2018-16-05 | Prodcut3 |
内容的提问来源于stack exchange,提问作者sim simo
相关产品推荐
相关产品推荐

