2013-10-28 5 views
4

У меня есть следующий SQL заявление:левое внешнее соединение на нескольких столах

select 
    a.desc 
    ,sum(bdd.amount) 
    from t_main c 
    left outer join t_direct bds on (bds.repid=c.id) 
    left outer join tm_defination def a on (a.id =bds.sId) 
    where c.repId=1000000134 
    group by a.desc; 

Когда я запускаю его я получаю следующий результат:

desc  amount 
    NW   12.00 
    SW   10 

Когда я пытаюсь добавить еще один левый внешнее соединение в получить еще один набор значений:

select 
    a.desc 
    ,sum(bdd.amount) 
    ,sum(i.amt) 
    from t_main c 
    left outer join t_direct bds on (bds.repid=c.id) 
    left outer join tm_defination def a on (a.id =bdd.sId) 
    left outer join t_ind i on (i.id=c.id) 
    where c.repId=1000000134 
    group by a.desc; 

Это в основном удваивает поле суммы, как:

  desc amount amt 
     NW  24.00 234.00 
     SE  20.00 234.00 

В то время как результат должен быть:

 desc amount amt 
     NW  12.00 234.00 
     SE  10.00 NULL 

Как это исправить?

+0

Вы используете псевдоним таблицы как bds, а в запросе u используется bdd, что может вызвать проблему. –

+0

Спасибо, я исправил его. Это был тип размещения здесь. –

+1

Проблема, вероятно, связана с тем, что вы группируете поле из 'a', которое является частью левого внешнего соединения. Попробуйте добавить 'c.id' как к части' SELECT', так и к 'GROUP BY'. – GregHNZ

ответ

6

Ваше новое левое внешнее соединение заставляет несколько строк возвращаться в результирующем наборе несколько раз из-за множественных отношений. Удалите СУММ и просто просмотрите возвращенные строки и выработайте именно те из них, которые вам нужны (возможно, ограничьте их по определенному типу записи t_ind, если это применимо?), А затем соответствующим образом настройте свой запрос.

5

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

select x.[desc], x.amount, y.amt 
from 
(
    select 
     c.[desc] 
     , sum (bdd.amount) as amount 
     , c.id 
    from t_main c 
    left outer join t_direct bds on (bds.repid=c.id) 
    left outer join tm_defination_def bdd on (bdd.id = bds.sId) 
    where c.repId=1000000134 
    group by c.id, c.[desc] 
) x 
left join 
(
    select t.id, sum (t.amt) as amt 
    from t_ind t 
    inner join t_main c 
     on t.id = c.id 
    where c.repID = 1000000134 
    group by t.id 
) y 
on x.id = y.id 

В первом суб-выбор вы будете получать агрегированные данные для двух первых столбцов: desc и amount, сгруппированным, как вам нужно. Второй выбор вернет необходимое значение amt для каждого id первого набора. Левое соединение между этими результатами даст нужный результат. Добавление таблицы t_main ко второму выбору было выполнено из-за проблем с производительностью.

Другим решением может быть следующее:

select 
    c.[desc] 
    , sum (bdd.amount) as amount 
    , amt = (select sum (amt) from t_ind where id = c.id) 
from #t_main c 
left outer join t_direct bds on (bds.repid=c.id) 
left outer join tm_defination_def bdd on (bdd.id = bds.sId) 
where c.repId = 1000000134 
group by c.id, c.[desc] 

Результат будет тем же самым. В принципе, вместо использования вложенных выборок вычисление суммы amt выполняется в строке для каждой строки результатов. В случае больших таблиц производительность второго решения будет хуже, чем первая.

Смежные вопросы