2013-09-23 4 views
3

У меня проблема с командами SUM, LEFT OUTER JOIN и GROUP BY, но не могу понять, где моя ошибка.Дублирование, включающее SUM, LEFT JOIN и GROUP BY

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

Пример транзакция таблица:

Transactions: 
Customer | Transaction Year | Amount 
------------------------------------- 
A  | 2007    | 100 
A  | 2008    | 80 
A  | 2008    | 50 
A  | 2009    | 210 

Пример претензии таблица:

Claims: 
Customer | Claim Year | Amount 
------------------------------- 
A  | 2007  | 30 
A  | 2007  | 40 
A  | 2009  | 110 

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

Desired Output: 
Customer | Year | Transaction Amount | Claim Amount 
---------------------------------------------------- 
A  | 2007 | 100    | 70 
A  | 2008 | 130    | NULL 
A  | 2009 | 210    | 110 

Я использовал команду левое внешнее соединение с GROUP BY команды для клиента и значения года. Но я получаю дублирование значения суммы транзакции, а множественное число относится к числу совпадающих строк в таблице Claims.

Таким образом, используя мой пример данных я получаю следующее:

Actual Output: 
Customer | Year | Transaction Amount | Claim Amount 
---------------------------------------------------- 
A  | 2007 | 200    | 70 
A  | 2008 | 130    | NULL 
A  | 2009 | 210    | 110 

В 2007 году, есть две претензии, которые уже привели к значению Transactions.Amount умножается на два (когда есть три претензии, Transaction.Amount утроился и т. д.).

Мой код выглядит следующим образом:

SELECT Transactions.Customer, 
    Transactions.Year, 
    sum(Transactions.Transaction Amount), 
    sum(Claims.Claim Amount) 
FROM Transactions 
    LEFT JOIN Claims ON Claims.Customer = Transactions.Customer 
     AND Transactions.Year = Claims.Year 
GROUP BY Transactions.Customer, Transactions.Year 

ли ложь в ответ подзапросов? Я не знаком с ними, поэтому любые указатели будут замечательными. Благодарю.

+0

Вы можете попробовать положить отдельную статью? –

+0

DISTINCT не изменит результат, поскольку он работает по строкам таблицы результатов (которые теперь различаются), а не по столбцам. – Peadar

ответ

3

Итак, первым шагом, чтобы увидеть, что происходит, является удаление СУММ и просто выберите сумму транзакции и сумму претензии. Таким образом вы можете видеть, какие данные возвращаются. Вы увидите, что соединение на A/2007 будет иметь сумму транзакции дважды, так как она соединяет каждую строку с таблицей претензий.

Одним из решений является использование подзапросов, как вы сказали, для выполнения SUM отдельно до присоединения.

SELECT 
    Transactions.Customer, 
    Transactions.Year, 
    SumTransaction, 
    SumClaim 
FROM (
     select Customer, Year, sum(Transaction Amount) SumTransaction 
     from Transactions 
     group by Customer, Year 
    ) Transactions 
    LEFT JOIN (
     select Customer, Year, sum(Claim Amount) sumClaim 
     from Claims 
     group by Customer, Year 
    ) Claims 
    ON Claims.Customer = Transactions.Customer 
     AND Transactions.Year = Claims.Year 

Другое возможное решение с учетом ваших ограничений:

SELECT 
    Transactions.Customer, 
    Transactions.Year, 
    SUM(Transaction Amount), 
    (SELECT SUM(Claim Amount) from Claims where Claims.Customer = Transactions.Customer and Claims.Year = Transactions.Year) 
FROM 
    Transactions 
GROUP BY 
    Customer, Year 

Третье возможное решение !! Это не требует никаких подзапросов! Смотрите это SQL Fiddle

select 
    t.Customer, 
    t.Year, 
    sum(distinct t.Amount), 
    sum(c.Amount) 
from 
    Transactions t 
    left join Claims c 
     on t.Customer = c.Customer 
      and t.Year = c.year 
group by 
    t.Customer, 
    t.Year 
+2

Вы забыли «group by» в подзапросах – alfasin

+0

Теперь у вас есть +1 от меня;) хороший ответ! – alfasin

+0

То, что я получаю за попытку сделать это, пока я работаю;) –

-1
With T as (
    SELECT Customer, 
      [Transaction Year], 
      sum(Amount) AS TransactionAmount 
    FROM Transactions 
    GROUP BY Customer, [Transaction Year] 
), C AS 
    SELECT Customer, 
      [Claim Year], 
      sum(Amount) as ClaimAmount 
    FROM Claims 
    GROUP BY Customer, [Claim Year] 
) 
SELECT T.Customer, 
     [Transactions Year], 
     TransactionAmount, 
     ClaimAmount 
FROM T 
    LEFT JOIN C ON C.Customer = T.Customer 
     AND [Transactions Year] = [Claim Year] 
+0

Это помечено как MySql, у которого нет функций CTE. –

+0

Спасибо, не понял. – Scormer

0

Запрос будет подсчитывая сумму сделки в два раза за 2007 год в связи с тем, у вас есть две претензии, так что сумма сделки будет учитываться дважды.

i.e.возвращаемые данные, используемые в:

Customer | Transaction Year | Transaction Amount | Claim Amount 
---------------------------------------------------------------- 
A  | 2007    | 100    | 30 
A  | 2007    | 100    | 40 
A  | 2008    | 80     | 
A  | 2008    | 50     | 
A  | 2009    | 210    | 110 

Что-то вроде следующего, хотя и не очень, должно решить проблему:

SELECT 
    t.Customer 
    ,t.Year 
    ,[Transaction Amount] = SUM(t.[Transaction Amount]) 
    ,[Claim Amount] = c.[Claim Amount] 
FROM 
    Transactions t 
    LEFT JOIN (
     SELECT 
      Customer 
      ,Year 
      ,SUM([Claim Amount]) 
     FROM 
      Claims 
     GROUP BY 
      Customer, Year 
    ) c ON c.Customer = t.Customer c.Year = t.Year 
GROUP BY t.Customer, t.Year, c.[Claim Amount]