#sql #postgresql #aggregate-functions
Вопрос:
Я хочу получить MIN
значение из столбца и соответствующее date
SELECT date, MIN(speed) FROM foo
INNER JOIN bar
ON foo.id = bar.foo_id;
Это не работает
Дата столбца должна использоваться в ГРУППЕ ПО или в другой агрегатной функции
Я не понимаю, почему я не могу выбрать дату, где MIN(speed)
находится. Он в той же строке, просто еще один атрибут…
Ответ №1:
Причина, по которой вы не можете делать то, что хотите, заключается в том, что SQL определяется не так. Я не думаю, что ваша версия была бы очень полезной. В конце концов, что бы сделал ваш запрос, если бы вы это сделали AVG(speed)
? Или и MIN(speed)
то и другое и MAX(speed)
?
В любом случае, то, что вы хотите сделать, достаточно просто с помощью ORDER BY
:
SELECT date, speed
FROM foo JOIN
bar
ON foo.id = bar.foo_id
ORDER BY speed
LIMIT 1;
Ответ №2:
Я не понимаю, почему я не могу выбрать дату, где MIN(скорость)
Агрегатная функция уменьшает количество строк до одной строки. Результат min(speed)
без ГРУППЫ ПО (как вы его использовали) дает одно значение (и строку), но у вас будет несколько значений для date
столбца
Сообщение об ошибке говорит вам, что Postgres не просто выберет для вас случайное значение, и вам нужно указать какое-то правило, чтобы выбрать нужное значение даты или комбинацию даты и скорости.
Комментарии:
1. Теперь я это понимаю. Я не знал, что
MIN()
это агрегатор — и я думаю, что в этом нет особого смысла (насколько мне известно). Потому что зачем вам агрегировать, когда требуется минимальное значение? Это можно легко сделать, просто сказав: «это строка с минимальным значением». Но, может быть, это потому, что Postgres каким-то образом работает внутренне так, как я не понимаю, и именно поэтому это делается так.2. @Stophface: ну, вот как определяется «агрегат» в SQL — он сводит множество строк к одной строке, например
sum()
, ведет себя одинаково.
Ответ №3:
Как указано в сообщении об ошибке, вам необходимо включить date
столбец в GROUP BY
:
SELECT date,
MIN(speed)
FROM foo
INNER JOIN bar ON foo.id = bar.foo_id
GROUP BY date;