умножение значений левого соединения - PullRequest
1 голос
/ 24 июля 2011

У меня есть следующие запросы -

SELECT COUNT(capture_id) as count_captures 
  FROM captures 
 WHERE user_id = 9

... возвращает 5

SELECT COUNT(id) as count_items 
  FROM items 
 WHERE creator_user_id = 9

... возвращает 22 * ​​1007 *

Я попробовал следующий запрос -

   SELECT COUNT(capture_id) as count_captures, 
          COUNT(items.id) as count_items 
     FROM captures 
LEFT JOIN items ON captures.user_id = items.creator_user_id 
    WHERE user_id = 9

... но он возвращает два столбца с 110 в качестве значения. Я хотел бы 5 в одном столбце и 22 в другом. Что я делаю не так?

Ответы [ 4 ]

3 голосов
/ 24 июля 2011

Мое колено - подзапрос:

select count(capture_id) as count_captures, 
    (select count(id) as count_items
         from items i where i.creator_user_id = captures.user_id) as count_items 
from captures 
where user_id = 9

Я не совсем уверен, что вы можете сделать, чтобы избежать этого.Вы видите ожидаемое (и в целом желаемое поведение).

Конечно, если вы знаете, что идентификаторы в обоих случаях не повторяются, вы можете использовать разные:

SELECT COUNT( DISTINCT capture_id) as count_captures, 
      COUNT( DISTINCT items.id) as count_items 
FROM captures 
LEFT JOIN items ON captures.user_id = items.creator_user_id 
    WHERE user_id = 9
2 голосов
/ 24 июля 2011

LEFT JOIN возвращает каждую строку в левой таблице с каждой строкой в ​​правой таблице, которая соответствует результатам. Поскольку все ваши идентификаторы одинаковы, что дает декартово произведение таблицы. (5 * 22 = 110).

Ожидается, что это произойдет.

1 голос
/ 24 июля 2011

Другой способ объединить два (казалось бы, не связанных) запроса в один:

SELECT
    ( SELECT COUNT(capture_id) 
        FROM captures 
       WHERE user_id = 9
    )
    AS count_captures 

  , ( SELECT COUNT(id) 
        FROM items 
       WHERE creator_user_id = 9
    )
    AS count_items 

В этих случаях нет необходимости использовать подзапросы или JOINХотя оптимизатор может быть достаточно умен, чтобы понять это, я бы не стал его путать.

1 голос
/ 24 июля 2011

Вы всегда можете объединить результаты (предупреждение, не проверено):

SELECT SUM(sub.count_captures), SUM(sub.count_items)
FROM (SELECT COUNT(capture_id) as count_captures, 0 as count_items 
from captures where user_id = 9
UNION
SELECT 0 as count_captures, count(id) as count_items
from items where creator_user = 9) sub
...