SQL左连接表时无匹配数据被过滤,需保留原记录求助
解决左连接丢失无匹配记录的问题
我懂你的困扰!你本来想用左连接保留A表(IntrastatFsum)里所有符合条件的公司和月份记录,但现在那些B表(Momsuppg)没有对应数据的记录都被过滤掉了——这是左连接的典型误区,问题出在WHERE子句里对B表字段的限制。
问题根源
当你用LEFT OUTER JOIN时,本来应该保留左表(A)的所有符合条件的记录,右表(B)没有匹配的话会返回NULL。但你把B.Ar = A.AR和A.Manad = B.Manad放在了WHERE子句里,这就会把左连接变成内连接:因为当B表没有匹配记录时,B的所有字段都是NULL,这些条件会判定为不成立,导致对应的A表记录被排除。
修改后的代码
把针对B表的匹配条件移到LEFT JOIN的ON子句中,同时用ISNULL()把NULL值替换成0(如果需要的话):
SELECT Tillnr = A.tillnr, Orgnr = A.orgnr, Månad = A.Manad, Intrastat = A.varde, Moms = ISNULL(B.vardeutf, 0) -- 把NULL替换为0,不需要的话可以直接写B.vardeutf INTO #Tabell1 FROM IntrastatFsum A LEFT OUTER JOIN Momsuppg B ON A.Orgnr = B.Orgnr AND B.Ar = A.AR -- 移到ON子句 AND A.Manad = B.Manad -- 移到ON子句 WHERE A.Orgnr IN (165563137933, 165020456017, .......) AND A.Ar = 2017 AND A.Manad = 9 AND A.InfUtf = 'U'
关键修改说明
- 把B表的匹配条件移到ON子句:这样左连接会先完成匹配,保留A表所有符合WHERE条件的记录,B表无匹配时字段为NULL
- 用ISNULL处理NULL值:如果希望B表无数据时显示0而不是NULL,就用
ISNULL(B.vardeutf, 0),不需要的话直接保留B.vardeutf即可 - A表的过滤条件留在WHERE:这些是针对A表本身的筛选,放在WHERE里没问题,不会影响左连接的结果
这样修改后,那些B表没有对应数据的公司和月份记录就会被保留下来,Moms字段要么是B表的数值,要么是0(或NULL,看你需求)。
内容的提问来源于stack exchange,提问作者A.Salehi




