Объединить запрос с двумя разными предложениями / условиями WHERE в одном

0

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

-- This will return all user ids with a count of "calculated" scores
SELECT u.id AS user_id, count(1) AS total FROM scores s
  INNER JOIN accounts a ON s.account_id = a.id
  INNER JOIN user u ON a.user_id = u.id
WHERE s.status = 'CALCULATED'
GROUP BY user_id;

-- This will return all user ids with a count of non-calculated scores
SELECT u.id AS user_id, count(1) AS failures FROM scores s
  INNER JOIN accounts a ON s.account_id = a.id
  INNER JOIN user u ON a.user_id = u.id
WHERE s.status <> 'CALCULATED'
GROUP BY user_id;

Но я хотел бы вернуть что-то вроде этого: user id, total, failures... все в одном запросе!

Теги:

2 ответа

3
Лучший ответ

Это можно сделать с условной агрегацией. Условия в SUM возвращаются 1 или 0 в зависимости от выполняемого условия.

SELECT u.id AS user_id,
SUM(s.status='CALCULATED'),
SUM(s.status<>'CALCULATED') AS total 
FROM scores s
INNER JOIN accounts a ON s.account_id = a.id
INNER JOIN user u ON a.user_id = u.id
GROUP BY u.id;
  • 0
    ...это было быстро! Спасибо!
1

В качестве примечания вы можете упростить свой запрос, поскольку таблица user (предположительно) не нужна:

SELECT a.user_id,
       SUM(s.status = 'CALCULATED') as num_calc,
       SUM(s.status <> 'CALCULATED') AS num_notcalc 
FROM scores s INNER JOIN
     accounts a
     ON s.account_id = a.id
GROUP BY a.user_id;

Ваши запросы дают правильный ответ, но вам также может быть необходимо соблюдать значения NULL. Если это вызывает беспокойство, используйте <=> оператор равенства NULL -safe:

SELECT a.user_id,
       SUM(s.status = 'CALCULATED') as num_calc,
       SUM(NOT s.status <=> 'CALCULATED') AS num_notcalc 
FROM scores s INNER JOIN
     accounts a
     ON s.account_id = a.id
GROUP BY a.user_id;
  • 0
    Действительно, таблица users не нужна при таком подходе; также использование NULL -безопасного оператора равенства - супер-приятный совет. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню