SQL多表关联查询 如何将第二张表行转为列按配置分组输出
错误原因
原有写法报错核心是关联子查询仅匹配了DocumentID,未关联对应的ConfigurationID,同一文档存在多个配置项时,每个子查询会返回所有配置下相同VariableID的多条值,触发子查询返回多行的错误。临时表写法没有做分组聚合,自然会把每个变量值单独拆成一行。
正确查询写法
优先使用条件聚合实现,写法兼容性强、执行效率高,适配所有主流SQL数据库:
SELECT d.Filename, MAX(CASE WHEN vv.VariableID = 55 THEN vv.ValueCache END) AS Attr1, MAX(CASE WHEN vv.VariableID = 56 THEN vv.ValueCache END) AS Attr2, MAX(CASE WHEN vv.VariableID = 172 THEN vv.ValueCache END) AS Attr3, c.ConfigName AS Configuration FROM Documents d INNER JOIN VariableValues vv ON d.DocumentID = vv.DocumentID INNER JOIN Configuration c ON vv.ConfigurationID = c.ConfigurationID WHERE vv.VariableID IN (55, 56, 172) GROUP BY d.DocumentID, d.Filename, c.ConfigurationID, c.ConfigName ORDER BY d.Filename, c.ConfigurationID
如果使用SQL Server等支持PIVOT函数的数据库,也可以用行转列函数实现,效果完全一致:
SELECT Filename, [55] AS Attr1, [56] AS Attr2, [172] AS Attr3, ConfigName AS Configuration FROM ( SELECT d.Filename, vv.VariableID, vv.ValueCache, c.ConfigName FROM Documents d INNER JOIN VariableValues vv ON d.DocumentID = vv.DocumentID INNER JOIN Configuration c ON vv.ConfigurationID = c.ConfigurationID WHERE vv.VariableID IN (55,56,172) ) src PIVOT( MAX(ValueCache) FOR VariableID IN ([55], [56], [172]) ) pvt
逻辑说明
- 先通过内连接把文档、变量值、配置三张表关联,得到的基础结果集每一行对应「单个文档+单个配置+单个变量」的组合
- 按文档+配置维度分组,通过条件判断把不同VariableID对应的ValueCache提取到独立列,使用
MAX聚合仅为满足SQL分组语法要求,同分组下每个VariableID只会对应一个值,不会改变原始结果 - 该写法不需要临时表、多层嵌套子查询,无论存在多少个配置项,都能正确返回「一行对应一个文档+一个配置」的结果,不会出现多行报错问题。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

