Здравствуйте. У меня есть база данных MySQL версии <b>8.3.0</b> с такой структурой: <br/> <pre><code>id - int [AI] player_count - int timestamp - timestamp [CURRENT_TIMESTAMP, on update]</code></pre> <br/> Каждые 30 минут добавляется новая строка с актуальным значением <b>player_count</b> и <b>timestamp</b>. <br/> <br/> Мне нужно сделать выборку максимального значения <b>player_count</b> за определённый период, например, за месяц, и получить не только это значение, но и соответствующий <b>timestamp</b>. <br/> <br/> Затем я планирую объединить полученные результаты и отобразить график с максимальными значениями за неделю/месяц на протяжении более длительного времени (например, месяц, полгода, год и т.д.). <br/> <pre><code class="sql">SELECT MAX(player_count) AS players_max, `timestamp` FROM steam_stats WHERE MONTH(`timestamp`) = 7 AND YEAR(`timestamp`) = 2024</code></pre> <br/> Однако, при выполнении этого запроса возникает ошибка: <br/> <pre><code>1140 - In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column 'db.steam_stats.timestamp'; this is incompatible with sql_mode=only_full_group_by</code></pre> <br/> Если я исключаю <b>`timestamp`</b> из SELECT, то получаю нужное значение, но не знаю, какому <b>timestamp</b> оно соответствует. <br/> <br/> Как правильно сформулировать SELECT и использовать GROUP BY, чтобы не отключать режим <b>sql_mode=only_full_group_by</b>?
Чтобы правильно выбрать максимальное значение `player_count` за определённый период и получить соответствующий `timestamp`, необходимо использовать подзапрос. Это поможет избежать ошибки, связанной с режимом `sql_mode=only_full_group_by`. В данном случае мы можем сначала найти максимальное значение и его `timestamp` в подзапросе, а затем использовать полученные результаты в основном запросе. Вот пример SQL-запроса, который осуществляет это: ```sql SELECT player_count AS players_max, timestamp FROM steam_stats WHERE timestamp = ( SELECT timestamp FROM steam_stats WHERE MONTH(timestamp) = 7 AND YEAR(timestamp) = 2024 ORDER BY player_count DESC LIMIT 1 ); ``` ### Разбор запроса: 1. **Внутренний подзапрос**: - Он сначала выбирает `timestamp` из таблицы `steam_stats`, где месяц равен 7 и год равен 2024. - Используя `ORDER BY player_count DESC LIMIT 1`, мы получаем `timestamp` максимального значения `player_count`. 2. **Внешний запрос**: - Здесь мы выбираем `player_count` и `timestamp` из таблицы `steam_stats`, который соответствует найденному `timestamp` в подзапросе. Таким образом, вы получите максимальное значение `player_count` и его соответствующий `timestamp` без нарушения правила `only_full_group_by`.
Ну типа так:
SELECT DISTINCT MAX(player_count) OVER () AS players_max, FIRST_VALUE(`timestamp`) OVER (ORDER BY player_count DESC) AS players_max_timestamp FROM steam_stats WHERE `timestamp` >= '2024-07-01' AND `timestamp` < '2024-08-01'
Если максимальное значение player_count встречается более чем один раз, то будет выведен случайный timestamp из возможных. Если нужен определённый (например, самый последний из них), расширьте выражение сортировки в определении окна.
SELECT player_count, `timestamp` FROM steam_stats WHERE `timestamp` >= TIMESTAMP('2024-07-01') AND `timestamp` < TIMESTAMP('2024-08-01') ORDER BY player_count DESC LIMIT 1