SQL Left加入求和列的加倍值

时间:2011-04-06 21:52:56

标签: sql sum left-join

我有2个需要查询的表,并根据table1中字段的总和是否等于table2中字段的总和(其他列匹配),返回“异常”的结果集。

select A.TranName,A.TranDate,A.TranCode,SUM(A.TranQty) AS T1Qty,B.TranName,B.TranDate,B.TranCode,SUM(B.TranQty) AS T2Qty
from Table1 AS A
LEFT JOIN Table2 AS B
on A.TranName = B.TranName AND A.TranDate = B.TranDate AND A.TranCode = B.TranCode
GROUP BY A.TranName, A.TranDate, A.TranCode, B.TranName, B.TranDate, B.TranCode
HAVING SUM(A.TranQty) != SUM(B.TranQty)

结果集不正确,因为它将Table1.TranQty总和乘以从Table2返回的行数。

例如,如果Table1有1条记录,其中连接匹配Table2中的2条记录,则表1中1条记录的TranQty将乘以2(因此不正确匹配)。

我确定我遗漏了一些关于在左连接中使用聚合函数(sum)的基本知识。

感谢您的帮助!

(系统是MSSql)

2 个答案:

答案 0 :(得分:6)

尝试此查询。基本上,您应单独汇总A和B的结果,然后验证计数。

select a.TranName,a.TranDate,a.TranCode
from (
select TranName,TranDate,TranCode, SUM(TranQty) AS T1Qty
Table1 
group by TranName,TranDate,TranCode) a
LEFT JOIN
(
select TranName,TranDate,TranCode, SUM(TranQty) AS T1Qty
Table2 
group by TranName,TranDate,TranCode) b
on (A.TranName = B.TranName AND A.TranDate = B.TranDate AND 
    A.TranCode = B.TranCode)
where a.T1Qty != b.T1Qty

确保这三列的组合足以在A和B中定义一行。如果有其他行,您可能还需要添加它们。

答案 1 :(得分:0)

它正在按照你的要求去做(但这不是你预期的那样)。表1中的每一行将在结果集中至少重复一次。如果它匹配表2中的多于一行,那么它将多次出现。

在查看原始SQL时,您似乎想要完成的是:

select *
from      ( select TranName ,
                   TranDate ,
                   TranCode ,
                   TranQTy = sum(TranQty)
            from Table1
            group by TranName ,
                     TranDate ,
                     TranCode
          ) A
full join ( select TranName ,
                   TranDate ,
                   TranCode ,
                   TranQTy = sum(TranQty)
            from Table2
            group by TranName ,
                     TranDate ,
                     TranCode
          ) B
where (    A.TranQty is     null and B.TranQty is not null
        OR A.TranQty is not null and B.TranQty is     null
        OR A.TranQt != B.TranQty
      )

您希望找到每个摘要的两个集合之间的差异。