2016-06-28 1 views
1

Я пытаюсь получить сумму строк при применении левого соединения с более чем одной таблицей. Кажется, он создает матрицу результата, которая приводит к неправильной функции суммы.Левое соединение с суммой с более чем 1 таблицей дает неправильную сумму

Пример:

первой таблицы: Клиент

второй таблице: TotalAssets

третьей таблице: TotalLiability

Структура таблицы:

Заказчик

CustID(int) CustomerName(varchar) 
1   Abc 
2   Def 
3   Ghi 

TotalAssets

CustID  Amount 
1   2000 
1   1000 
2   600 

TotalLiability

CustID  Amount 
1   1000 
1   1000 
2   800 

Выход Ожидаемое

CustID TotalAssets TotalLiability 
1   3000   2000 
2   600   800 

Текущий запрос

Select c.CustID , Sum(a.Amount) , Sum(l.Amount) From Customer c 
left join TotalAssests a on a.CustID = c.CustID 
left join TotalLiability l on l.CustID = c.CustID 
Group by c.CustID 

Проблема с этим текущим запросом является сумма не является правильным, как я думаю, что первый слева присоединиться к созданию первого набора с несколькими записями, а затем второй один применяется.

Любая помощь приветствуется

UPDATE:

Я нахожу немного удачи, следуя методу, но это, кажется, плохой/Hacky вариант, как в моем случае, у меня есть более 7-8 элементов в группе и от добавление большего количества левых предложений приводит к сложному управлению запросами.

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

Select Set1.CustID , Set1.TotalAssets, Sum(l.Amount) from (Select c.CustID , Sum(a.Amount) as TotalAssets From Customer c 
left join TotalAssests a on a.CustID = c.CustID 
Group by c.CustID)Set1 
left join TotalLiability l on l.CustID = Set1.CustID. 
Group by Set1.CustID , Set1.TotalAssets 
+2

Что неожиданный результат? – artm

+1

И какой результат вы получаете? Не заставляйте нас анализировать структуру таблиц и создавать собственные тестовые данные. – Blorgbeard

+0

@artm Я переписал свой вопрос с образцом вывода и коротким запросом с образцами данных. –

ответ

2

Я думаю, что это получает вас, что вы хотите с минимальной сложностью:

select c.CustId, isnull(a.Amount, 0) as TotalAssets, isnull(l.Amount, 0) as TotalLiability 
from Customers c 
left join (
    select CustId, sum(Amount) as Amount from TotalAssets group by CustId 
) a on a.CustId = c.CustId 
left join (
    select CustId, sum(Amount) as Amount from TotalLiability group by CustId 
) l on l.CustId = c.CustId 

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

0

Это должно работать:

Select c.CustID 
, (select sum(a.amount) from TotalAssests a where a.CustId = c.CustID) as SumAsset 
, (select Sum(l.Amount) TotalLiability l where l.CustID = c.CustID) as SumLiability 
From Customer c 
+0

Коррелированные подзапросы не самые результативные, но они должны работать, и их проще поддерживать. – Blorgbeard

-2

Надежда ниже работает с меньшим количеством обслуживания,

DECLARE @Customer TABLE (CustID int, CustomerName varchar(50)) DECLARE @TotalAssets TABLE (CustID int, Amount INT) DECLARE @TotalLiability TABLE (CustID int, Amount INT) 
INSERT INTO @Customer 
SELECT 1, 
     'ABC' 
UNION 
SELECT 2, 
     'DEF' 
UNION 
SELECT 3, 
     'GHI' 

--Select * From @Customer 

INSERT INTO @TotalAssets 
SELECT 1, 
     2000 
UNION 
SELECT 1, 
     1000 
UNION 
SELECT 2, 
     600 

--Select * From @TotalAssets 

INSERT INTO @TotalLiability 
SELECT 1, 
     1000 
UNION 
SELECT 1, 
     1000 
UNION 
SELECT 2, 
     800 

--Select * From @TotalLiability 

SELECT * 
FROM @Customer 
SELECT C.CustID, 
     C.CustomerName, 
     Sum(A.Amount) TotalAssets, 
     Sum(L.Amount) TotalLiability 
FROM @Customer C 
JOIN @TotalAssets A ON C.CustID = A.CustID 
JOIN @TotalLiability L ON C.CustId = L.CustID 
GROUP BY C.CustID, 
     C.CustomerName 
+0

'UNION' вместо' UNION ALL' дает вам неправильные данные теста. Кроме того, я не думаю, что это дало бы правильные результаты в любом случае - соответствует ли результат выходному сигналу OP при его тестировании? – Blorgbeard

+0

Это сработало для меня. Pl. попробуйте с вашего конца. – Lucky

+0

Это только «работает», потому что ваши тестовые данные ошибочны. Сделайте 'select * from @ TotalLiability' - обратите внимание, что дублированные строки не были вставлены? Это потому, что ваш «союз» должен быть «объединен всем». – Blorgbeard

-1

Попробуйте это:

select R.CustID, sum(R.AA), sum(R.AL) from (
select c.CustID, null AA, sum(a.amount) AL 
From @Customer c 
left join @TotalAssests a on a.CustID = c.CustID 
Group by c.CustId 
union all 
select c.CustID , sum(l.amount) AA, null AL 
From @Customer c 
left join @TotalLiability l on l.CustID = c.CustID 
Group by c.CustId) R group by R.CustID 
Смежные вопросы