Здравствуйте. У меня есть база данных 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