PostgreSQL array_agg order

Таблица "животные":

animal_name animal_type
Tom         Cat
Jerry       Mouse
Kermit      Frog

Запрос:

SELECT 
array_to_string(array_agg(animal_name),';') animal_names,
array_to_string(array_agg(animal_type),';') animal_types
FROM animals;

Ожидаемый результат:

Tom;Jerry;Kerimt, Cat;Mouse;Frog
OR
Tom;Kerimt;Jerry, Cat;Frog;Mouse

Могу ли я быть уверен, что порядок в первой агрегатной функции всегда будет такой же, как во второй. Я имею в виду, я не хотел бы получить:

Tom;Jerry;Kermit, Frog;Mouse,Cat

4 ответа

Решение

Если вы используете версию PostgreSQL < 9.0, тогда:

От: http://www.postgresql.org/docs/8.4/static/functions-aggregate.html

В текущей реализации порядок ввода в принципе не определен. Однако, как правило, подача входных значений из отсортированного подзапроса будет работать. Например:

ВЫБЕРИТЕ xmlagg(x) ОТ (ВЫБЕРИТЕ x ОТ ЗАКАЗА ПО УМОЛЧАНИЮ) как вкладка;

Так что в вашем случае вы бы написали:

SELECT
array_to_string(array_agg(animal_name),';') animal_names,
array_to_string(array_agg(animal_type),';') animal_types
FROM (SELECT animal_name, animal_type FROM animals) AS x;

Входные данные для array_agg будут неупорядоченными, но они будут одинаковыми в обоих столбцах. И если хотите, можете добавить ORDER BY пункт к подзапросу.

Используйте ORDER BY, как этот пример из руководства:

SELECT array_agg(a ORDER BY b DESC) FROM table;

По словам Тома Лейна :

... Если я правильно понял, OP хочет быть уверенным, что две агрегатные функции будут видеть данные в * одном и том же * неуказанном порядке. Я думаю, что это довольно безопасное предположение. Сервер должен был бы сделать все возможное, чтобы сделать по-другому, и он этого не делает.

... Таким образом, задокументировано поведение, согласно которому агрегат без собственного ORDER BY будет видеть строки в любом порядке, в котором их предоставляет предложение FROM.

Поэтому я считаю правильным предположить, что все агрегаты, ни один из которых не использует ORDER BY, в вашем запросе будут видеть входные данные в одном и том же порядке. Однако сам порядок не указан (который зависит от порядка, в котором предложение FROM предоставляет строки).

Источник: список рассылки PostgreSQL .

Сделай это:

      SELECT 
    array_to_string(array_agg(animal_name order by animal_name),';') animal_names,
    array_to_string(array_agg(animal_type order by animal_type),';') animal_types
FROM 
    animals;
Другие вопросы по тегам