如何合并三个独立INNER JOIN查询结果为单一主表并实现同表展示?
当然可以合并!这里有几种实用方法
你的三个查询都是从Documents和VariableValue关联,只是过滤的VariableID不同,想要把它们的结果合并成一个包含Filename、Description、Status、Revision的主表,完全没问题,给你几个常用的实现方式:
方法1:使用CASE表达式(通用所有SQL数据库)
这种方法通过条件判断把不同VariableID的ValueText映射到不同列,最后按Filename聚合,得到一行对应一个文件的结果:
SELECT Documents.Filename, MAX(CASE WHEN VariableValue.VariableID = '56' THEN VariableValue.ValueText END) AS Description, MAX(CASE WHEN VariableValue.VariableID = '46' THEN VariableValue.ValueText END) AS Status, MAX(CASE WHEN VariableValue.VariableID = '45' THEN VariableValue.ValueText END) AS Revision FROM Documents INNER JOIN VariableValue ON Documents.DocumentID = VariableValue.DocumentID WHERE RIGHT(filename,6) = 'SLDDRW' AND VariableValue.VariableID IN ('56','46','45') GROUP BY Documents.Filename;
解释:
CASE语句会根据VariableID匹配对应的ValueText,不匹配的返回NULLMAX()聚合函数用来把同一个Filename的多行结果合并成一行(忽略NULL值)- 最后通过
IN条件一次性过滤需要的VariableID,比三个单独查询更高效
方法2:多次关联VariableValue表
如果每个文件在三个VariableID下都有对应的值,也可以通过多次INNER JOIN来实现:
SELECT d.Filename, desc_vv.ValueText AS Description, status_vv.ValueText AS Status, rev_vv.ValueText AS Revision FROM Documents d INNER JOIN VariableValue desc_vv ON d.DocumentID = desc_vv.DocumentID AND desc_vv.VariableID = '56' INNER JOIN VariableValue status_vv ON d.DocumentID = status_vv.DocumentID AND status_vv.VariableID = '46' INNER JOIN VariableValue rev_vv ON d.DocumentID = rev_vv.DocumentID AND rev_vv.VariableID = '45' WHERE RIGHT(d.filename,6) = 'SLDDRW';
注意:如果某个文件缺少其中一个VariableID的记录,这个方法会过滤掉该文件,如果你想保留所有文件,可以把INNER JOIN换成LEFT JOIN。
方法3:使用PIVOT(部分数据库支持,如SQL Server、Oracle)
如果你的数据库支持PIVOT操作,代码会更简洁:
SELECT Filename, [56] AS Description, [46] AS Status, [45] AS Revision FROM ( SELECT Documents.Filename, VariableValue.ValueText, VariableValue.VariableID FROM Documents INNER JOIN VariableValue ON Documents.DocumentID = VariableValue.DocumentID WHERE RIGHT(filename,6) = 'SLDDRW' AND VariableValue.VariableID IN ('56','46','45') ) AS SourceTable PIVOT ( MAX(ValueText) FOR VariableID IN ([56], [46], [45]) ) AS PivotTable;
PIVOT本质上是把行数据转成列,和CASE表达式的逻辑类似,但语法更简洁。
关于“声明变量后合并”的问题
你也可以先把每个查询的结果存成临时表或者CTE(公共表表达式),然后再通过JOIN合并,比如:
WITH DescriptionCTE AS ( SELECT Documents.Filename , VariableValue.ValueText FROM Documents INNER JOIN VariableValue ON Documents.DocumentID = VariableValue.DocumentID WHERE RIGHT(filename,6) = 'SLDDRW' AND VariableID = '56' ), StatusCTE AS ( SELECT Documents.Filename , VariableValue.ValueText FROM Documents INNER JOIN VariableValue ON Documents.DocumentID = VariableValue.DocumentID WHERE RIGHT(filename,6) = 'SLDDRW' AND VariableID = '46' ), RevisionCTE AS ( SELECT Documents.Filename , VariableValue.ValueText FROM Documents INNER JOIN VariableValue ON Documents.DocumentID = VariableValue.DocumentID WHERE RIGHT(filename,6) = 'SLDDRW' AND VariableID = '45' ) SELECT d.Filename, d.ValueText AS Description, s.ValueText AS Status, r.ValueText AS Revision FROM DescriptionCTE d JOIN StatusCTE s ON d.Filename = s.Filename JOIN RevisionCTE r ON d.Filename = r.Filename;
这种方式和方法2的逻辑类似,只是先把每个子集单独提取出来,可读性更好,但性能上和方法2差不多。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

