SQL Left Join удваивает значение суммируемых столбцов - PullRequest
4 голосов
/ 07 апреля 2011

У меня есть 2 таблицы, к которым мне нужно запросить и вернуть результирующий набор «исключений», основанный на том, равна ли сумма поля в таблице1 сумме поля в таблице2 (где совпадают другие столбцы).

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 запись, где объединение совпало с 2 записями вВ таблице 2 значение TranQty из 1 записи в таблице 1 будет умножено на 2 (и, следовательно, будет совпадать неправильно).

Я уверен, что мне не хватает чего-то базового в использовании агрегатной функции (суммы) в левом соединении,

Спасибо за помощь!

(Система MSSql)

Ответы [ 2 ]

6 голосов
/ 07 апреля 2011

Попробуйте этот запрос .. В основном, вы должны агрегировать результаты 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. Если есть дополнительные строки, возможно, вам придется добавить их тоже.

0 голосов
/ 07 апреля 2011

Он делает именно то, что вы просили (но это не то, что вы ожидали). Каждая строка из таблицы 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
      )

Вы хотите найти разницу между двумя наборами, каждый из которых представляет собой резюме.

...