Я ищу способ объединить строки поля в группе по запросу. Так, например, у меня есть таблица:
ID COMPANY_ID EMPLOYEE
1 1 Anna
2 1 Bill
3 2 Carol
4 2 Dave
и я хотел сгруппировать по company_id, чтобы получить что-то вроде:
COMPANY_ID EMPLOYEE
1 Anna, Bill
2 Carol, Dave
В mySQL есть встроенная функция для этого group_concat
sql
postgresql
group-by
string-aggregation
Парень с
источник
источник
Ответы:
PostgreSQL 9.0 или более поздняя версия:
В последних версиях Postgres (с конца 2010 года) есть
string_agg(expression, delimiter)
функция, которая будет выполнять именно то, о чем спрашивался вопрос, даже позволяя указать строку разделителя:В Postgres 9.0 также добавлена возможность указывать
ORDER BY
предложение в любом агрегированном выражении ; в противном случае порядок не определен. Теперь вы можете написать:Или действительно:
PostgreSQL 8.4 или более поздняя версия:
PostgreSQL 8.4 (в 2009 году) представил функцию агрегирования,
array_agg(expression)
которая объединяет значения в массив. Затемarray_to_string()
можно использовать, чтобы дать желаемый результат:string_agg
для версий до 8.4:В случае, если кто-то сталкивается с этим в поисках прокладки совместимости для баз данных до 9.0, можно реализовать все,
string_agg
кромеORDER BY
пункта.Таким образом, с приведенным ниже определением это должно работать так же, как в 9.x Postgres DB:
Но это будет синтаксическая ошибка:
Протестировано на PostgreSQL 8.3.
Пользовательские варианты (все версии Postgres)
До 9.0 не было встроенной агрегатной функции для объединения строк. Простейшая пользовательская реализация ( предложенная Вайда Габо в этом посте списка рассылки , среди многих других) заключается в использовании встроенной
textcat
функции (которая скрывается за||
оператором):Вот
CREATE AGGREGATE
документация.Это просто склеивает все строки без разделителя. Чтобы вставить «,» между ними, не имея его в конце, вы можете создать собственную функцию конкатенации и заменить ее на «textcat» выше. Вот один, который я собрал и протестировал на 8.3.12:
Эта версия будет выводить запятую, даже если значение в строке равно нулю или пусто, поэтому вы получите такой вывод:
Если вы предпочитаете удалить лишние запятые для вывода этого:
Затем добавьте
ELSIF
проверку к функции следующим образом:источник
array_to_string(array_agg(employee), ',')
?Order By
предложение внутри агрегатной функции, напримерstring_agg(employee, ',' Order By employee)
Как насчет использования встроенных в Postgres функций массива? По крайней мере, на 8.4 это работает из коробки:
источник
Начиная с PostgreSQL 9.0 вы можете использовать агрегатную функцию с именем string_agg . Ваш новый SQL должен выглядеть примерно так:
источник
Я не претендую на кредит за ответ, потому что нашел его после некоторого поиска:
Чего я не знал, так это того, что PostgreSQL позволяет вам определять свои собственные агрегатные функции с помощью CREATE AGGREGATE.
Этот пост в списке PostgreSQL показывает, насколько просто создать функцию, которая выполняет то, что требуется:
источник
Как уже упоминалось, создание собственной агрегатной функции является правильным решением. Вот моя агрегатная функция конкатенации (вы можете найти подробности на французском ):
);
И затем используйте это как:
источник
Этот последний фрагмент списка объявлений может быть интересен, если вы будете обновляться до 8.4:
Я бы сослался на документы по разработке 8.4, но они пока еще не перечислили эту функцию.
источник
В продолжение ответа Кева, используя документы Postgres:
Сначала создайте массив элементов, затем используйте встроенную
array_to_string
функцию.источник
Еще раз повторяем использование пользовательской агрегатной функции конкатенации строк: вам нужно помнить, что оператор select будет размещать строки в любом порядке, поэтому вам нужно будет выполнить дополнительный выбор в операторе from с предложением order by , и затем внешний выбор с предложением group by для агрегирования строк, таким образом:
источник
Я нашел эту документацию PostgreSQL полезной: http://www.postgresql.org/docs/8.0/interactive/functions-conditional.html .
В моем случае я искал простой SQL для конкатенации поля с квадратными скобками, если поле не пустое.
источник
Используйте
STRING_AGG
функцию для PostgreSQL и Google BigQuery SQL :источник
В соответствии с версией PostgreSQL 9.0 и выше вы можете использовать агрегатную функцию, называемую string_agg. Ваш новый SQL должен выглядеть примерно так:
источник
Вы также можете использовать функцию форматирования. Который также может неявно заботиться о преобразовании типов text, int и т. Д. Сам по себе.
источник
Я использую Jetbrains Rider, и было хлопотно копировать результаты из приведенных выше примеров для повторного выполнения, потому что казалось, что все это обернуто в JSON. Это объединяет их в одно утверждение, которое было легче выполнить
источник
Если вы используете Amazon Redshift, где string_agg не поддерживается, попробуйте использовать listagg.
источник