Я работаю над запросом, который должен быть максимально универсальным для повторного использования. Запрос включает GROUP BY.
Однако я не могу указать столбцы, так как мне нужно, чтобы они были универсальными.
Цель запроса:
- Назначает ключ времени каждой строке, используя столбец даты.
- Затем я использую GROUP BY, чтобы получить только несколько значений группы.
- В основном то, что я хочу сделать, это уменьшить количество очков в данный день.
- Итак, если есть, скажем, 4 точки в день, я использую GROUP BY, чтобы уменьшить их до 2 точек в день, а затем выбрать то же самое, скажем, в новую базу данных.
Запрос
SELECT * FROM
(SELECT h.* FROM testdb h
WHERE h.date <= '2016-01-02 23:30:00'
GROUP BY FLOOR(UNIX_TIMESTAMP(h.date)/((1440/2)*60))
UNION
SELECT c.* FROM testdb c
WHERE c.date> '2016-01-02 23:30:00') m;
Я могу запустить вышеуказанный запрос в MySQL v5.7 и выше, отключив режим ONLY_FULL_GROUP_BY. Когда я это делаю, результат запроса меняется.
Результат MySQL ‹5.7: 17 строк.
MySQL > 5.7 (с отключенной полной группой) результат 18 строк.
Мои сомнения:
- Почему набор результатов меняется, группа не должна фактически изменять результат в моем случае.
- Любая работа, чтобы добиться того же, не отключая FULL GROUP BY?
Читал про MySQL ANY_VALUE, но опять же не работает с SELECT ANY_VALUE(*)
Нужна помощь в том, как добиться вышеперечисленного :) Спасибо
Обновление 1
Локальный компьютер:
Версия SQL 5.7.24
Режим SQL:
STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
Спорный запрос:
SELECT * FROM
(SELECT h.* FROM testdb h
WHERE h.date <= '2016-01-02 23:30:00'
GROUP BY FLOOR(UNIX_TIMESTAMP(h.date)/((1440/2)*60))
UNION
SELECT c.* FROM testdb c
WHERE c.date> '2016-01-02 23:30:00') m;
Действия для воспроизведения проблемы:
CREATE TABLE testdb ( id int primary key auto_increment,date timestamp);
INSERT INTO testdb (date) VALUES ('2015-12-31 00:00:00');
INSERT INTO testdb (date) VALUES ('2015-12-31 06:00:00');
INSERT INTO testdb (date) VALUES ('2015-12-31 18:00:00');
INSERT INTO testdb (date) VALUES ('2016-01-01 00:00:00');
INSERT INTO testdb (date) VALUES ('2016-01-01 06:00:00');
INSERT INTO testdb (date) VALUES ('2016-01-01 18:00:00');
INSERT INTO testdb (date) VALUES ('2016-01-02 00:00:00');
INSERT INTO testdb (date) VALUES ('2016-01-02 06:00:00');
INSERT INTO testdb (date) VALUES ('2016-01-02 18:00:00');
INSERT INTO testdb (date) VALUES ('2016-12-31 00:00:00');
INSERT INTO testdb (date) VALUES ('2016-12-31 06:00:00');
INSERT INTO testdb (date) VALUES ('2016-12-31 06:01:00');
INSERT INTO testdb (date) VALUES ('2016-12-31 12:00:00');
INSERT INTO testdb (date) VALUES ('2016-12-31 18:00:00');
INSERT INTO testdb (date) VALUES ('2017-01-01 00:00:00');
INSERT INTO testdb (date) VALUES ('2017-01-01 06:00:00');
INSERT INTO testdb (date) VALUES ('2017-01-01 18:00:00');
INSERT INTO testdb (date) VALUES ('2017-01-02 00:00:01');
INSERT INTO testdb (date) VALUES ('2017-01-02 06:00:00');
INSERT INTO testdb (date) VALUES ('2017-01-02 18:00:00');
Результат запроса:
18 рядов
Скрипка БД
https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=6082783c8a2c8ab1aa9bb5846
Версия SQL 5.7.26
РЕЖИМ SQL
STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION
Результат запроса:
17 рядов
SET sql_mode = '';
-- я получаю 17 строк. Между тем, что вы получаете с предложением Гордона? - person Rick James   schedule 28.06.2019sql_mode=''
илиSELECT h.*
илиSELECT ANY_VALUE(h.id), ...
вы можете сделатьSELECT MIN(h.id), ...
. - person Rick James   schedule 28.06.2019SELECT * FROM (...)
можно удалить. - person Rick James   schedule 28.06.2019