PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Можем ли да дефинираме функция GROUP_CONCAT в PostgreSQL?

Има вграден string_agg(), който прави това, което искате, но вие изрично искате да бъде наречен group_concat за съвместимост с MySQL. За съжаление, string_agg() използва вътрешен тип данни за натрупване (вероятно за да избегне копирането на целия буфер при всяко добавяне, но не съм погледнал източника) и не намерих начин да декларирам SQL aggrerate, идентичен на string_agg( ).

Дефинирането на функция group_concat() също няма да работи, тъй като pg трябва да бъде наясно, че е агрегат, а не функция със скрит агрегат вътре, което няма да работи. Такава функция би работила с един ред в даден момент:всеки агрегат вътре просто ще агрегира един ред и ще го върне непроменен...

По този начин този код ще натрупа елементите в масив, след което ще добави разделителите "," с array_to_string. Ще използвам декларацията array_agg() (преди да стане вградена) като модел и просто ще добавя функция за финализиране, която ще преобразува обобщения масив в текст.

CREATE OR REPLACE FUNCTION _group_concat_finalize(anyarray)
RETURNS text AS $$
    SELECT array_to_string($1,',')
$$ IMMUTABLE LANGUAGE SQL;

CREATE AGGREGATE group_concat(anyelement) (
   SFUNC=array_append,
   STYPE=anyarray,
   FFUNC=_group_concat_finalize,
   INITCOND='{}'
);

SELECT group_concat(x) FROM foo;

Хубавото е, че трябва да работи добре за всеки тип, без проблеми, благодарение на общите типове "anyarray" и "anyelement".

Предполагам, че това ще бъде по-бавно от string_agg(), ако string_agg наистина избягва да копира целия масив за агрегиране при всяко добавяне. Това обаче трябва да има значение само ако броят на редовете, които трябва да бъдат групирани във всеки набор, е голям. В този случай вероятно можете да отделите минута за редактиране на SQL заявката;)

http://sqlfiddle.com/#!17/c452d/1



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използвайте колони, генерирани от Postgres, в модела Sequelize

  2. Автоматично премахване на таблици и индекси, по-стари от 90 дни

  3. Dense_rank първо конвертиране на Oracle в Postgresql

  4. Не може да се свърже с PostgreSQL сървър

  5. Кога връзката се затваря при извикване на .close() на JooQ DSLContext, ако изобщо се затваря?