2013-07-10 3 views
2

У меня есть 2 таблицы с той же схемой userID, категория, счет. Мне нужен запрос, чтобы суммировать количество каждой пары userID/category. Иногда пара будет существовать в одном столе, а не в другом. У меня возникли проблемы с присоединением без потери строк, в которых пара идентификаторов пользователей/категорий существует только в одной таблице. Это то, что я пытаюсь (без успеха):SQL-соединение без потери строк

select a.user, a.category, count=a.count+b.count 
from #temp1 a join #temp2 b 
on a.user = b.user and a.category = b.category 

Пример:

Вход:

user category count 
id1  catB  3 
id2  catG  9 
id3  catW  17 

user category count 
id1  catB  1 
id2  catM  5 
id3  catW  13 

Желаемая Выход:

user category count 
id1  catB  4 
id2  catG  9 
id2  catM  5 
id3  catW  30 

Update: "Количество" является а не фактическое имя столбца. Я просто использовал его для этого примера, и я забыл, что это зарезервированное слово.

+0

Почему ID2 не суммируется? он находится в обеих таблицах. –

+0

@SNash, категории отличаются. Возможно, вам захочется перечитать требования к суммированию. –

ответ

4

Вам нужно:

  1. Используйте полное внешнее соединение, чтобы не уронить строки, присутствующие в одной таблице, а не другой
  2. Coalesce рассчитывает до того, поскольку 0 + NULL = NULL

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

Таким образом, используя все из этих руководящих принципов, ваш запрос будет выглядеть так:

SELECT COALESCE(a.user, b.user) AS user, 
     COALESCE(a.category, b.category) AS category, 
     COALESCE(a.[count],0) + COALESCE(b.[count],0) AS [count] 
FROM #temp1 AS a 
FULL OUTER JOIN #temp2 AS b 
      ON a.user = b.user AND 
       a.category = b.category 
+0

Отлично! Я не знал о COALESCE, это именно то, что мне нужно. Я также считаю, что «AS [count]» является посторонним, поскольку у вас есть «[count] =» в начале этой строки. – JCB

+0

@JCB, я хотел удалить часть '' '[count] =' '', которую я сделал в последнем редактировании. Спасибо что подметил это. –

1

Одним из способов решения этой проблемы является полным внешним соединением:

select coalesce(a.user, b.user) as user, 
     coalesce(a.category, b.category) as category, 
     coalesce(a.count, 0) + coalesce(b.count, 0) as "count" 
from #temp1 a full outer join 
    #temp2 b 
    on a.user = b.user and 
     a.category = b.category; 

При использовании full outer join, вы должны быть потому что ключевые поля могут быть NULL, когда есть совпадение только в одной таблице. В результате, select имеет тенденцию иметь много coalesce() s (или аналогичные конструкции).

Другой способ использует union all запрос с агрегацией:

select "user", category, SUM(count) as "count" 
from ((select "user", category, "count" 
     from #temp1 
    ) union all 
     (select "user", category, "count" 
     from #temp2 
    ) 
    ) t 
group by "user", category