user_of_toster
@user_of_toster

Чем отличается ORDER BY от WITHIN GROUP (ORDER BY) простым языком?

Читаю документацию про aggregation expression.

aggregation_function(expression, ORDER BY a) - в начале сортирует таблицу по а, затем применяет aggregation_function к получившемуся списку.

А что делает aggregation_function(expression), WITHIN GROUP (ORDER BY a) ? Прочел эту часть документации много раз, объяснения не понятны для новичка.
  • Вопрос задан
  • 131 просмотр
Решения вопроса 1
@galaxy
aggregation_function(expression, ORDER BY a) - в начале сортирует таблицу по а, затем применяет aggregation_function к получившемуся списку.

Да, только запятая в скобках лишняя. Такой синтаксис позволяет иметь агрегатам в списке SELECT сортировку входных значение (напомню, что ORDER BY в запросе вычисляется после GROUP BY и агрегации, т.е. чтобы раньше так сделать, был нужен подзапрос, который отсортирует массив данных), даже каждому агрегату свою (раньше вообще нельзя было сделать нормально). Агрегатным функциям часто не важен порядок входных значений (COUNT, SUM, MAX - не зависят от порядка), но есть функции, для которых он значение имеет (string_agg, etc, можно свои также написать).

А что делает aggregation_function(expression), WITHIN GROUP (ORDER BY a)

Это синтаксис для специального вида агрегатов: Ordered-Set Aggregate Functions и Hypothetical-Set Aggregate Functions (запятая тут у вас тоже лишняя). Обычные с ним не заработают.
Они принимают на вход отсортированный массив данных, указанный в ORDER BY (т.е. a, а не expression!), плюс, возможно, значение expression (вычисляется один раз за запрос).
Область применения пока достаточно специфична: Ordered-Set Aggregate Functions по сути применяется только для вычисления перцентилей (зато их стало легко и приятно считать:
SELECT percentile_disc (0.2) WITHIN GROUP (ORDER BY ...)
).
Hypothetical-Set Aggregate Functions - это такие аналоги некоторых WINDOW агрегатов (типа rank):
SELECT rank() OVER (ORDER BY value) ...; -- вернет ранк данной записи в отсортированном по value списке
SELECT rank(55) WITHIN GROUP (ORDER BY value) ...; -- вернет ранк числа 55, как если бы оно было в  отсортированном по value списке


В общем, штука своеобразная. Читайте документацию, сходу может быть трудно понять.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы