Неправильный результат при выборе счетчика с помощью функции order by и math в MySQL 5.7.17
У меня есть простая таблица с именем temp
с тремя столбцами и следующими данными:
# c1 c2 v
1 1 'a'
1 2 'b'
1 1 'b'
1 2 'a'
Я запускаю запрос:
SELECT
t01.c1,
t01.c2,
COUNT(DISTINCT v) AS cnt
FROM
(
SELECT
FLOOR(c1) AS c1,
FLOOR(c2) AS c2,
v
FROM
temp
) AS t01
GROUP BY
t01.c1,
t01.c2
ORDER BY
cnt DESC
Это должно возвращать следующее:
# c1, c2, cnt
1, 1, 2
1, 2, 2
Но на самом деле он возвращает это:
# c1, c2, cnt
1, 1, 1
1, 2, 1
1, 1, 1
1, 2, 1
Это странно, когда он содержит команду floor по группе подсчитывать разные, а результат неверно - он не группирует данные.
Является ли это ошибкой MySQL в версии 5.7.17?
Ответы
Ответ 1
Да, это ошибка, связанная с объединением производной таблицы (подзапрос в FROM
) во внешний запрос. Пожалуйста, сообщите об ошибке в bugs.mysql.com.
Обходные:
- Установить
optimizer_switch='derived_merge=off';
- Добавьте предложение
LIMIT
в подзапрос. Это будет препятствовать его объединению во внешний запрос.
- Вручную объединить подзапрос с внешним запросом:
SELECT
FLOOR(c1) AS g1,
FLOOR(c2) AS g2,
COUNT(DISTINCT v) AS cnt
FROM temp
GROUP BY g1, g2
ORDER BY cnt DESC;
Ответ 2
Он просто попробовал это в MySql 5.6 на sqlfiddle, и он просто работает. И дальше
dbfiddle в MySql 5.7 это не так.
Итак, возможно, что-то с MySql 5.7, как вы уже подумали.
В соответствии с Справочное руководство по MySql в разделе (Функции, устаревшие в MySQL 5.7)
GROUP BY неявно сортирует по умолчанию (то есть, в отсутствие ASC или DESC), но полагаясь на неявную сортировку GROUP BY MySQL 5.7 устарел. Для достижения определенного порядка сортировки сгруппированных результатов, предпочтительнее использовать. Чтобы создать заданный порядок сортировки, используйте явные обозначения ASC или DESC для столбцов GROUP BY или Предложение ORDER BY. Сортировка GROUP BY - это расширение MySQL, которое может меняться в будущем выпуске; например, чтобы сделать возможным оптимизатор для упорядочения группировок любым способом, который он считает наиболее эффективно и избегать служебных данных сортировки.
Обновление
Я попробовал что-то другое для вас, которое работает:
SELECT
t01.c1,
t01.c2,
count(v) AS cnt
FROM
(
SELECT
DISTINCT v as v,
FLOOR(c1) AS c1,
FLOOR(c2) AS c2
FROM
temp
) AS t01
GROUP BY
t01.c1,
t01.c2
ORDER BY
cnt DESC
Это мой оператор create:
CREATE TABLE temp
(`c1` int, `c2` int, `v` varchar(5))
;
INSERT INTO temp
(`c1`, `c2`, `v`)
VALUES
(1, 1, '''a'''),
(1, 1, '''a'''),
(1, 2, '''b'''),
(1, 1, '''b'''),
(1, 1, '''c'''),
(1, 2, '''a''')
;
результат:
https://www.db-fiddle.com/f/7zBFKzd3pE7ymrD5LTcmkz/1