Da dieses Thema regelmäßig gefragt wird, alleine in den letzten 3 Tagen jeden Tag durch einen anderen:
http://www.pg-forum.de/sql/4056-abfr...html#post22200
http://www.pg-forum.de/sql/4058-menge-ermitteln.html
http://www.pg-forum.de/sql/4065-kein...html#post22277
erkläre ich mal ganz kurz, wie sowas geht.
Vorweg: eine Datenbank ist keine Tabellenkalkulation. Damit meine ich, daß solche Operationen eigentlich nicht typisch für eine Datenbank sind. Tabellen haben typischerweise wenig Spalten, aber können potenziell sehr, sehr viele Zeilen enthalten. Jeder, der versucht, Zeilen zu Spalten zu wandeln, sollte sich vorher fragen, ob dies wirklich notwendig ist.
Was tun, wenn man es dennoch will?
Nun, zuerst ist zu prüfen, ob die Aggregation von Zeilen zu einer vorher definierten Anzahl von Spalten führt. Dies ist z.B. dann der Fall, wenn die Zeilen, die später die definierenden Spalten darstellen, exakt bekannt sind. Beispiel: Datumsangaben, daraus sollen 12 Spalten für die einzelnen Monate entstehen.
Es funktioniert nicht mehr (bzw. anders), wenn die Anzahl der entstehenden Spalten nicht definierbar ist. Dies sollte gegebenenfalls mit Hilfe von Referenztabellen, Check-Constraints oder ENUM-Typen sichergestellt werden, ansonsten wird das Resultat u.U. fehlerhaft.
Zur Abfrage selber: der 'Trick' basiert auf Anwendung von PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: Conditional Expressions .
Nachfolgend 2 Beispiele, die das gut demonstrieren sollten:
In beiden Beispielen sind die entstehenden Spalten mir vorher bekannt. Ist dies nicht der Fall, wird es schwerer. Entweder man verwendet eine Stored Procedure, welche zur Laufzeit die entstehenden Spalten berechnet, daraus dynamisch einen String erstellt (welcher das SQL mit den einzelnen CASE ... enthält) und führt diesen mittels EXECUTE aus, oder man verwendet aus dem Contrib-Modul tablefunc die crosstab - Funktion: PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: tablefuncCode:begin; create table category (category text, member text); copy category from stdin delimiter ';'; fruit;apple fruit;pear fruit;banana vegetable;potato vegetable;beet vegetable;cucumber \. select array_to_string(array_agg(case when category = 'fruit' then member else NULL end),',') as "Fruit", array_to_string(array_agg(case when category = 'vegetable' then member else NULL end),',') as "Vegetable" from category; rollback; begin; create table rain (town text, date date, amount int); copy rain from stdin delimiter ';'; town a;2009-07-01;10 town a;2009-07-10;5 town a;2009-08-12;15 town b;2009-07-05;3 town c;2009-07-04;10 town c;2009-07-06;12 town c;2009-07-08;8 town c;2009-08-15;22 \. select town, sum(case when extract(month from date) = 7 then amount else 0 end) as "July", sum(case when extract(month from date) = 8 then amount else 0 end) as "August" from rain group by town order by town; rollback;
Andreas
--
Papa-Kind-Kur vom 8. bis 29. September ;-)
PostgreSQL Hosting
http://www.amazon.de/gp/registry/2APKFICAIYMWBads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
https://www.xing.com/profile/Andreas_Kretschmer7
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen