Сортировать текстовый агрегат, созданный с помощью array_agg в postgresql - PullRequest
22 голосов
/ 11 августа 2010

У меня есть таблица в postgresql. Следующая таблица "животные" сделает, чтобы объяснить мою проблему:

name
------
tiger
cat
dog

Сейчас я использую следующий запрос:

SELECT
    array_to_string(array_agg("name"), ', ')
FROM
    animals;

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

"cat, dog, tiger".

Итак, как мне отсортировать строковый массив в postgresql 8.4 перед его преобразованием в строку. ORDER BY в строке «имя» не работает, а встроенная функция сортировки обрабатывает только целые значения.

Кто-нибудь хорошая идея, как решить это в чистом SQL?

Большое спасибо Ричард

Ответы [ 6 ]

46 голосов
/ 22 сентября 2011

Для современного PostgreSQL (начиная с версии 9.0) вы можете использовать предложение ORDER BY в агрегированном выражении :

SELECT
    array_to_string(array_agg(name ORDER BY name), ', ')
FROM
    animals;

Кроме того, для вашей конкретной цели вы можете использовать string_agg для упрощения запроса:

SELECT
    string_agg(name, ', ' ORDER BY name)
FROM
    animals;
14 голосов
/ 11 августа 2010

Это будет доступно в PostgreSQL 9.0:

http://www.postgresql.org/docs/9.0/static/release-9-0.html, Раздел E.1.3.6.1. Заполнители

Тем временем вы можете сделать что-то подобное, что может решить проблему (хотя и неуклюже):

SELECT array_agg(animal_name)
FROM (
    SELECT "name" AS animal_name
    FROM animals
    ORDER BY "name"
) AS sorted_animals;
4 голосов
/ 11 августа 2010

Хотя ответ Мэтью Вуда лучше для вашего случая, вот способ сортировки массивов в PostgreSQL 8.4 и выше:

SELECT array(
    SELECT unnest(array[3,2,1]) AS x ORDER BY x
);

Знание функций array и unnest может быть удобно, так какон также позволяет вам делать такие вещи, как "map" над массивом:

SELECT array(
    SELECT x*x FROM (SELECT unnest(array[1,2,3]) AS x) as subquery
);

Опять же, это может быть вашим по цене PostgreSQL 8.4.

0 голосов
/ 25 сентября 2018

Чтобы обновить этот вопрос, Snowflake реализовал сортировку массива:

SELECT
    array_sort(array_agg("name")
FROM
    animals;

Также можно использовать array_sort_by для сортировки объекта

0 голосов
/ 03 марта 2013

Тем не менее, для версии 8.4, используя решение, предложенное Мэтью Вудом, если вам нужно выполнить группировку во внешнем запросе, внутренний запрос также должен быть отсортирован, чтобы сортировка была последовательной.

SELECT family, array_agg(animal_name)
FROM (
    SELECT family, "name" AS animal_name
    FROM animals
    ORDER BY family, "name"
) AS sorted_animals
group by family;
0 голосов
/ 11 августа 2010

Вы пытались использовать generate_series() для массива, а затем сделать SELECT...ORDER BY для этого результата (или просто вставить его в SELECT) перед тем, как преобразовать его в строку?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...