Запрос MySQL COUNT возвращает только одно значение из выражения CASE - PullRequest
1 голос
/ 17 марта 2019

У меня есть таблица со столбцом score, и в зависимости от количества баллов я хочу сгруппировать их по разным «эмитентам» и сосчитать их.

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

SELECT
  CASE
    WHEN score < 133 THEN 'Detractors'
    WHEN score BETWEEN 133 AND 209 THEN 'Passives'
    WHEN score = 210 THEN 'Promotors'
  END AS 'Issuer',
  COUNT(1) AS 'Amount'
FROM my_data 

Есть предложения о том, что происходит?

1 Ответ

1 голос
/ 17 марта 2019

Запрос, который содержит агрегатные функции (например, COUNT() или MAX()) без предложения GROUP BY, всегда будет возвращать ровно одну строку. Если столбец (даже вычисляемый столбец, такой как Issuer) потенциально может содержать различные значения, сервер должен выбрать одно из них.

Документация гласит:

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

В вашем случае Issuer может содержать три значения («Хулители», «Пассивы», «Промоторы»), и сервер добавил «Пассивы».

Обратите внимание, что при включенном режиме ONLY_FULL_GROUP_BY (который используется по умолчанию с версии 5.7) ваш запрос завершится с ошибкой.

ONLY_FULL_GROUP_BY

Отклонить запросы, для которых список выбора, HAVING условие или ORDER BY список относится к неагрегированным столбцам, которые не названы ни в GROUP BY и функционально не зависят от (определяется однозначно by) GROUP BY столбцы.

Решение в вашем случае довольно простое: включите GROUP BY Issuer в запрос

SELECT
  CASE
    WHEN score < 133 THEN 'Detractors'
    WHEN score BETWEEN 133 AND 209 THEN 'Passives'
    WHEN score = 210 THEN 'Promotors'
  END AS 'Issuer',
  COUNT(1) AS 'Amount'
FROM my_data 
GROUP BY `Issuer`
...