求助:对比两张表中代理的保单数量,内连接查询未达预期
问题分析与解决方案
首先,咱们先聊聊你原查询的问题出在哪:
1. Inner Join 过滤了表A独有的代理
你用了INNER JOIN,这会只保留两张表中都有匹配代理的记录。表A里的1015、1018这些代理在表B里没有对应数据,自然就被过滤掉了,这就是你看不到它们的原因。
2. 统计结果计算错误
当你把表A和表B关联后,一个代理如果在表B中有多条记录,Join会产生重复的表A行。比如代理1011在表A里只有1条保单,但表B里有3条,Join后会变成3条记录,这时候count(a.policy_number)算的是Join后的行数(3),而不是表A中该代理实际的保单数量(1),结果自然不对。
3. 冗余的Group By
因为你用a.agent_pay = b.agent作为Join条件,这两个字段的值是完全相等的,Group By的时候只需要其中一个就够了,没必要两个都写。
针对需求的解决方案
你的需求是显示表A中所有代理的信息,同时包含那些和表B保单数量不匹配的代理(包括表B中没有的代理)。根据你给出的预期结果,这里提供两种方案:
方案1:显示表A代理的保单号 + 表B的保单数量
如果需要同时对比表A和表B的保单数量,可以用CTE先分别统计两张表的代理保单数,再用左连接关联:
WITH AgentAStats AS ( SELECT agent_pay, policy_number AS a_policy_number, COUNT(policy_number) AS a_policy_count -- 表A中该代理的保单数 FROM [AdventureWorksDW2012].dbo.[table1] GROUP BY agent_pay, policy_number ), AgentBStats AS ( SELECT agent, COUNT(policy_number) AS b_policy_count -- 表B中该代理的保单数 FROM [AdventureWorksDW2012].dbo.[table2] GROUP BY agent ) SELECT aa.agent_pay, aa.a_policy_number, ISNULL(ab.b_policy_count, 0) AS b_policy_count FROM AgentAStats aa LEFT JOIN AgentBStats ab ON aa.agent_pay = ab.agent -- 筛选出不匹配的代理:表B无数据,或两边保单数不等 WHERE ISNULL(ab.b_policy_count, 0) <> aa.a_policy_count
方案2:仅显示表A中不匹配的代理及其保单号
如果只需要像你预期结果那样显示agent_pay和对应的保单号,直接用左连接+子查询统计表B的数量即可:
SELECT a.agent_pay, a.policy_number FROM [AdventureWorksDW2012].dbo.[table1] a LEFT JOIN ( SELECT agent, COUNT(policy_number) AS b_count FROM [AdventureWorksDW2012].dbo.[table2] GROUP BY agent ) b ON a.agent_pay = b.agent -- 条件:表B中没有该代理,或表B的保单数不等于表A的(表A每个代理都是1条,所以用b_count <>1) WHERE b.agent IS NULL OR b.b_count <> 1
运行这个查询后,就能得到你想要的结果:包含表A里1011(表B保单数3≠1)、1015(表B无数据)、1018(表B无数据)以及1016(如果表A存在且表B无数据/数量不等)的记录。
内容的提问来源于stack exchange,提问作者Tirtha Roy Chowdhury
相关产品推荐
相关产品推荐

