You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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.

表结构及SQL代码截图

我尝试合并这四张表,请求帮助。


问题根源

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 20:03:14