SQL将trading_area、reporting_unit分为独立列展示查询结果
问题根因
当前查询返回双行的核心原因是你使用的是EAV(实体-属性-值)表结构设计,trading_area和reporting_unit是两条独立的属性记录,直接联表查询会把两个属性值输出到同一info_value列、拆成两行返回,需要通过行转列逻辑把不同类型的属性值映射到独立列。
实现方案
优先推荐使用兼容性最强的条件聚合写法,支持MySQL、PostgreSQL、SQL Server、Oracle等所有主流关系型数据库:
SELECT item.id_number AS id_num, item.name_item, MAX(CASE WHEN typ.type_id = 20005 THEN inf.info_value END) AS trading_area, MAX(CASE WHEN typ.type_id = 20001 THEN inf.info_value END) AS reporting_unit FROM traded_item item INNER JOIN item_info inf ON item.id_number = inf.item_id INNER JOIN item_info_types typ ON inf.info_type_id = typ.type_id WHERE typ.type_id IN (20005, 20001) GROUP BY item.id_number, item.name_item ORDER BY item.name_item;
- 写法说明:同一组
id_num+name_item下,每个type_id仅对应一个属性值,用MAX()/MIN()聚合不会改变取值,仅起到行合并的作用;同时将原SQL的隐式逗号联表改为显式INNER JOIN,可读性更高,可避免漏写连接条件引发笛卡尔积的风险。
如果使用的是支持PIVOT语法的数据库(SQL Server、Oracle等),也可以用专属行转列语法实现,以SQL Server为例:
SELECT id_number AS id_num, name_item, [20005] AS trading_area, [20001] AS reporting_unit FROM ( SELECT item.id_number, item.name_item, typ.type_id, inf.info_value FROM traded_item item INNER JOIN item_info inf ON item.id_number = inf.item_id INNER JOIN item_info_types typ ON inf.info_type_id = typ.type_id WHERE typ.type_id IN (20005, 20001) ) src PIVOT( MAX(info_value) FOR type_id IN ([20005], [20001]) ) pvt ORDER BY name_item;
返回效果
执行后输出结果完全匹配预期结构,每组id_num+name_item仅返回一行,两个属性独立成列:
| id_num | name_item | trading_area | reporting_unit |
|---|---|---|---|
| 1001 | YC | Washington | BOA |
| 1002 | NO | Utah | BCG |
| 1001 | GO | Arizona | NYP |
内容的提问来源于stack exchange,提问作者Skywalker
相关产品推荐
相关产品推荐

