sql >> Database >  >> RDS >> PostgreSQL

Kunnen we een GROUP_CONCAT-functie definiëren in PostgreSQL?

Er is een string_agg() ingebouwd die doet wat je wilt, maar je vraagt ​​specifiek om de naam group_concat voor MySQL-compatibiliteit. Helaas gebruikt string_agg() een intern gegevenstype voor accumulatie (vermoedelijk om te voorkomen dat de hele buffer op elke append wordt gekopieerd, ik heb echter niet naar de bron gekeken) en ik heb geen manier gevonden om een ​​SQL-aggregaat identiek te verklaren aan string_agg( ).

Het definiëren van de functie group_concat() zou ook niet werken, omdat pg moet worden opgemerkt dat het een aggregaat is, geen functie met een aggregaat erin verborgen, wat niet zou werken. Zo'n functie zou op één rij tegelijk werken:elk aggregaat binnenin zou gewoon een enkele rij aggregeren en deze ongewijzigd retourneren...

Deze code verzamelt dus de elementen in een array en voegt vervolgens de "," scheidingstekens toe met array_to_string. Ik zal de array_agg()-declaratie (voordat het ingebouwd werd) als een model gebruiken en gewoon een finalizer-functie toevoegen die de geaggregeerde array naar tekst converteert.

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;

Het leuke is dat het prima zou moeten werken voor elk type, zonder gedoe, dankzij de generieke typen "anyarray" en "anyelement".

Ik zou aannemen dat dit langzamer zou zijn dan string_agg() als string_agg inderdaad vermijdt om de hele aggregatie-array op elke append te kopiëren. Dit zou echter alleen van belang moeten zijn als het aantal rijen dat in elke set moet worden gegroepeerd groot is. In dit geval kunt u waarschijnlijk een minuutje besteden aan het bewerken van de SQL-query;)

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



  1. De verschillende manieren verkennen om uw MariaDB-gegevens te versleutelen

  2. Wordt de trigger BEFORE INSERT uitgevoerd voor elke rij in insert op dubbele sleutelupdatequery?

  3. Een nieuwe variabele gemaakt door een waarde uit een MySQL-tabel te halen

  4. ORA-00972 identifier is te lang alias kolomnaam