Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden
0800 1 255 255

SQL Concat Aggregationsfunktion

Für gezielte Datenbankexporte oder ‑views möchte man oft eine Zeile für einen Eintrag in der SQL Abfrage erhal­ten. Beim Verknüpfen von meh­re­ren Tabellen führt dies bei 1:n oder n:m Beziehungen zu dem Nachteil, dass für die Basistabelle meh­rere Zeilen ent­ste­hen. Zur Verdeutlichung sei fol­gen­des Beispiel (in PostgreSQL) gege­ben:

create table account (
ID BIGINT not null,
EMAIL CHARACTER VARYING(1024) not null unique,
primary key (ID)
);


create table history (
ID BIGINT not null,
ACCOUNT_FK BIGINT not null,
ENTRY CHARACTER VARYING(1024) not null unique,
primary key (ID)
);

Ziel soll es sein, ein Abfrage zu erstel­len, die alle Accounts und die dazu zuge­hö­ri­gen Historyeinträge zurück­lie­fert. Allerdings soll pro Account nur eine Zeile ver­wen­det wer­den.

Folgende Abfrage führt nicht zum Ziel:

select account.email, history.entry
from account, history
where account.id = history.account_fk;

Eine Möglichkeit ist es, die Einträge in der History zu ver­knüp­fen, z. B. über ein con­cat Funktion. Wenn diese als Aggregatfunktion zur Verfügung steht, kann diese in einem group by ver­wen­det wer­den.

In PostgreSQL ist dies wie folgt mög­lich:

CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);

Mit fol­gen­der Abfrage kommt man dann zu dem Ziel nur noch eine Zeile pro Account zu erhal­ten:


select account.email, textcat_all(history.entry || ',')
from account, history
where account.id = history.account_fk;
group by account.email

(Siehe dazu auch hier http://archives.postgresql.org/pgsql-novice/2003–09/msg00177.php)

In mysql ist dies noch ein­fa­cher, denn hier exis­tiert bereits eine sol­che Aggregationsfunktion: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

Related Posts

Pin It on Pinterest