Подсчет предметов с определенным состоянием, даже если сумма равна нулю в MySQL - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть две таблицы - элементы и их состояния. Каждый элемент имеет только одно состояние. Мне нужно получить список состояний с подсчитанными пунктами этого состояния, но только от определенной степени. Когда я удаляю часть WHERE, я получаю список всех состояний, но с его помощью я получаю только некоторые состояния, потому что в элементах с владельцем no.7 вообще не используются одни и те же состояния. Как получить все состояния, даже если их количество равно нулю?

Единственное решение, которое у меня есть, это использовать подзапрос вместо COUNT(i.id), но это будет намного медленнее, и я боюсь производительности.

Мои таблицы:

ID   STATE NAME
==   ==========
1    New
2    Used
3    Archived
4    Unknown

ID   STATE   ITEM NAME   OWNER
==   =====   =========   =====
1    1       ABC         7
2    2       DEF         6
3    3       GHI         7
4    1       JKL         7

Мой запрос:

SELECT
 s.id,
 s.name,
 COUNT(i.id) AS count
FROM
 b_items_states s
LEFT JOIN
 b_items i ON i.state = s.id
WHERE
 i.owner = 7
GROUP BY
 s.id

Мой результат:

ID   NAME      COUNT
==   ====      =====
1    New       2
3    Archived  1

Мой ожидаемый результат:

ID   NAME      COUNT
==   ====      =====
1    New       2
2    Used      0
3    Archived  1
4    Unknown   0

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

Переместите условие фильтрации внутри JOIN, как в:

SELECT
 s.id,
 s.name,
 COUNT(i.id) AS count
FROM
 b_items_states s
LEFT JOIN
 b_items i ON i.state = s.id AND i.owner = 7
GROUP BY
 s.id

Если вы поместите условие фильтрации в оператор WHERE, вы неявно преобразуете внешнее объединение во внутреннее соединение, даже без замечая.

0 голосов
/ 03 апреля 2020

Impaler имеет правильный ответ

Вы также можете express это как коррелированный подзапрос:

SELECT s.id, s.name,
       (SELECT COUNT(*)
        FROM b_items i
        WHERE i.state = s.id AND
              i.owner = 7
       ) as count
FROM b_items_states s;

В частности, это может использовать индекс на b_items(state, owner). Избегая внешнего агрегирования, оно должно иметь лучшую производительность.

...