SQL Server中JOIN与UNION联合多表查询报Msg205错误求助
求助:合并四张表时UNION操作报错的解决方法
我需要关联四张表(表结构见附图),目前有两段可正常运行的SQL,但无法获取全部所需数据:
可运行SQL1
SELECT * FROM Erste.dbo.Persons1$ LEFT OUTER JOIN Erste.dbo.Adresses1$ ON Erste.dbo.Persons1$.Id=Erste.dbo.Adresses1$.Id --LEFT OUTER JOIN Erste.dbo.Adresses2$ --ON Erste.dbo.Persons1$.Id=Erste.dbo.Adresses2$.Id UNION SELECT * From Erste.dbo.Persons2$ LEFT OUTER JOIN Erste.dbo.Adresses2$ ON Erste.dbo.Persons2$.Id=Erste.dbo.Adresses2$.Id
可运行SQL2
(注:SQL2与SQL1内容完全一致)
SELECT * FROM Erste.dbo.Persons1$ LEFT OUTER JOIN Erste.dbo.Adresses1$ ON Erste.dbo.Persons1$.Id=Erste.dbo.Adresses1$.Id --LEFT OUTER JOIN Erste.dbo.Adresses2$ --ON Erste.dbo.Persons1$.Id=Erste.dbo.Adresses2$.Id UNION SELECT * From Erste.dbo.Persons2$ LEFT OUTER JOIN Erste.dbo.Adresses2$ ON Erste.dbo.Persons2$.Id=Erste.dbo.Adresses2$.Id
当我取消注释Adresses2$的关联后,修改后的SQL无法运行:
报错SQL
SELECT * FROM Erste.dbo.Persons1$ LEFT OUTER JOIN Erste.dbo.Adresses1$ ON Erste.dbo.Persons1$.Id=Erste.dbo.Adresses1$.Id LEFT OUTER JOIN Erste.dbo.Adresses2$ ON Erste.dbo.Persons1$.Id=Erste.dbo.Adresses2$.Id UNION SELECT * From Erste.dbo.Persons2$ LEFT OUTER JOIN Erste.dbo.Adresses2$ ON Erste.dbo.Persons2$.Id=Erste.dbo.Adresses2$.Id
错误信息
Msg 205, Level 16, State 1, Line 1
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
我尝试合并这四张表,请求帮助。
问题根源
UNION的核心要求是:前后两个查询返回的列数必须完全一致,且对应列的数据类型要兼容。你修改后的第一段查询是Persons1$关联了Adresses1$和Adresses2$,返回列数为三张表的列总和;而第二段查询仅Persons2$关联Adresses2$,返回列数为两张表的列总和,两者列数不匹配,因此触发205错误。
两种解决办法
办法1:为缺失列补充NULL值
在第二段查询中,手动补充Adresses1$的所有列,用NULL填充,确保两边列数一致:
-- 第一段:Persons1关联两个地址表 SELECT p1.*, a1.*, a2.* FROM Erste.dbo.Persons1$ p1 LEFT JOIN Erste.dbo.Adresses1$ a1 ON p1.Id = a1.Id LEFT JOIN Erste.dbo.Adresses2$ a2 ON p1.Id = a2.Id UNION -- 第二段:Persons2关联Adresses2,补上Adresses1的列(用NULL填充) SELECT p2.*, -- 替换为Adresses1$的实际列名,依次列出所有列 NULL AS 地址1列1, NULL AS 地址1列2, -- ... 列出Adresses1$的全部列 a2.* From Erste.dbo.Persons2$ p2 LEFT JOIN Erste.dbo.Adresses2$ a2 ON p2.Id = a2.Id
办法2:先合并同类型表,再关联
先将两个Persons表、两个地址表分别合并,再进行关联,逻辑更清晰:
WITH 合并人员表 AS ( SELECT * FROM Erste.dbo.Persons1$ UNION ALL -- 无需去重时用UNION ALL,性能更优 SELECT * FROM Erste.dbo.Persons2$ ), 合并地址表 AS ( SELECT Id, '地址表1' AS 来源, * FROM Erste.dbo.Adresses1$ UNION ALL SELECT Id, '地址表2' AS 来源, * FROM Erste.dbo.Adresses2$ ) SELECT 人员.*, 地址.* FROM 合并人员表 人员 LEFT JOIN 合并地址表 地址 ON 人员.Id = 地址.Id
提示:尽量避免使用SELECT *,明确写出所需列,可避免因表结构变更导致的问题;无需去重时优先用UNION ALL,比UNION性能更好。
内容的提问来源于stack exchange,提问作者HELPMEDADDY
相关产品推荐
相关产品推荐

