多表关联SQL查询结果从纵向表转为横向表的实现方法咨询
问题描述
我拥有以下三张数据表:
1. 表:tblAttribute
| Id(编号) | attribute(属性) | dcControl(控制项) |
|---|---|---|
| 1 | LowTv | |
| 2 | fastNozzle | |
| 3 | LowNOx | PAR_LOW_NOX_ENG_ENABLE |
| 4 | TCCutOff | |
| 5 | WHR | |
| 6 | gtd311 | |
| 7 | none |
2. 表:tblTuning
| id(编号) | eng_id(引擎编号) | legislation(法规标准) | tuningMode(调优模式) |
|---|---|---|---|
| 1 | 1 | T2 | Delta |
| 2 | 1 | T1 | Delta |
| 3 | 1 | T1 | LLT |
| 4 | 1 | T2 | LLT |
| 5 | 1 | T2 | Std |
| 6 | 1 | T1 | Std |
| 7 | 2 | T2 | Delta |
| 8 | 2 | T1 | Delta |
| 9 | 2 | T1 | LLT |
| 10 | 2 | T2 | LLT |
| 11 | 2 | T1 | Std |
| 12 | 2 | T2 | Std |
3. 表:tblTuningMatrix
| id(编号) | itemID(条目编号) | tuningattr_id(调优属性编号) | tuningattr_value(调优属性值) |
|---|---|---|---|
| 1 | 1 | 1 | 1 |
| 2 | 2 | 1 | 0 |
| 3 | 3 | 1 | 1 |
| 4 | 4 | 1 | 0 |
| 5 | 5 | 1 | 0 |
当前关联三张表的查询语句如下:
select tuning.id, tuning.eng_id, tuningMatrix.tuningattr_value, tuning.tuningMode, tuning.legislation, tuningAttribute.attribute, tuningAttribute.dcControl from tuningMatrix inner join tuning on tuning.itemId=tuningMatrix.itemID inner join tuningAttribute on tuningAttribute.id=tuningMatrix.tuningattr_id WHERE tuning.deleted = 'false'
通过该查询得到纵向结构的结果表,但需要转换为横向结构。实际输出与期望输出如下:
期望输出
| id(编号) | eng_id(引擎编号) | tuningMode(调优模式) | legislation(法规标准) | dcControl(控制项) | LowTv | WHR | LowNox | TCCutOff | gtd311 | fastNozzle |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | Delta | T2 | null | 0 | 0 | 0 | 1 | 1 | 0 |
实际输出
| id(编号) | eng_id(引擎编号) | tuningMode(调优模式) | legislation(法规标准) | dcControl(控制项) | LowTv | WHR | LowNox | TCCutOff | gtd311 | fastNozzle |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 1 | Delta | T2 | 1 | 0 | NULL | 0 | 0 | 0 | |
| 1 | 1 | Delta | T2 | PAR_LOW_NOX_ENG_ENABLE | NULL | NULL | 0 | NULL | NULL | NULL |
| 2 | 1 | Delta | T2 | 0 | 0 | NULL | 0 | 0 | 0 | |
| 2 | 1 | Delta | T2 | PAR_LOW_NOX_ENG_ENABLE | NULL | NULL | 0 | NULL | NULL | NULL |
请问该如何修改查询语句以实现将结果从纵向表转为横向表的需求?
解决方案
要实现纵向转横向(行转列),可以使用条件聚合(CASE WHEN + 聚合函数)将每个属性转换为单独列,同时按tuning表的唯一标识分组,确保每条tuning记录只显示一行。
修改后的查询语句
SELECT t.id AS `id(编号)`, t.eng_id AS `eng_id(引擎编号)`, t.tuningMode AS `tuningMode(调优模式)`, t.legislation AS `legislation(法规标准)`, MAX(ta.dcControl) AS `dcControl(控制项)`, -- 为每个属性设置列,无对应值时显示0 COALESCE(MAX(CASE WHEN ta.attribute = 'LowTv' THEN tm.tuningattr_value END), 0) AS LowTv, COALESCE(MAX(CASE WHEN ta.attribute = 'WHR' THEN tm.tuningattr_value END), 0) AS WHR, COALESCE(MAX(CASE WHEN ta.attribute = 'LowNOx' THEN tm.tuningattr_value END), 0) AS LowNox, COALESCE(MAX(CASE WHEN ta.attribute = 'TCCutOff' THEN tm.tuningattr_value END), 0) AS TCCutOff, COALESCE(MAX(CASE WHEN ta.attribute = 'gtd311' THEN tm.tuningattr_value END), 0) AS gtd311, COALESCE(MAX(CASE WHEN ta.attribute = 'fastNozzle' THEN tm.tuningattr_value END), 0) AS fastNozzle FROM tblTuning t LEFT JOIN tblTuningMatrix tm ON t.id = tm.itemID LEFT JOIN tblAttribute ta ON tm.tuningattr_id = ta.id WHERE t.deleted = 'false' GROUP BY t.id, t.eng_id, t.tuningMode, t.legislation
关键说明
- LEFT JOIN替代INNER JOIN:确保即使某些
tuning记录没有对应的tuningMatrix或attribute数据,也能被保留,避免遗漏记录。 - 条件聚合:用
CASE WHEN匹配每个属性,结合MAX函数将同一tuning记录的多行属性值合并为一行;COALESCE把NULL值替换为0,贴合期望输出格式。 - 分组依据:按
tuning表的唯一字段(id、eng_id、tuningMode、legislation)分组,保证每条tuning记录只生成一行结果。 - dcControl处理:用
MAX(ta.dcControl)取该tuning记录对应的控制项(多值时取非空值),无对应值时显示NULL。
内容的提问来源于stack exchange,提问作者Srusti Thakkar
相关产品推荐
相关产品推荐

