Auch hier empfehle ich für mehr als nur ein paar "Datentypen" die Verwendung von crosstab()
:
SELECT * FROM crosstab(
$$SELECT DISTINCT ON (1, 2)
'max' AS "type", data_type, val
FROM tbl
ORDER BY 1, 2, val DESC$$
,$$VALUES ('Final Fantasy'), ('Quake 3'), ('World of Warcraft')$$)
AS x ("type" text, "Final Fantasy" int, "Quake 3" int, "World of Warcraft" int)
Rückgabe:
type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max | 500 | 1500 | 1200
Weitere Erläuterungen zu den Grundlagen:
PostgreSQL-Kreuztabellenabfrage
Dynamische Lösung
Das Schwierige ist, dies vollständig dynamisch zu machen :damit es funktioniert für
- eine unbekannte Nummer von Spalten (in diesem Fall data_types)
- mit unbekannten Namen (erneut data_types)
Zumindest der Typ ist bekannt:integer
in diesem Fall.
Kurz gesagt:Das ist mit aktuellem PostgreSQL (einschließlich 9.3) nicht möglich. Es gibt Annäherungen mit polymorphen Typen und Möglichkeiten, die Einschränkungen mit Arrays oder hstore-Typen zu umgehen. Kann gut genug für dich sein. Aber es ist streng nicht möglich um das Ergebnis mit einzelnen Spalten in einer einzigen SQL-Abfrage zu erhalten. SQL ist sehr streng in Bezug auf Typen und möchte wissen, was zurück zu erwarten ist.
Allerdings , es kann mit zwei gemacht werden Abfragen. Der erste erstellt die tatsächlich zu verwendende Abfrage. Aufbauend auf dem obigen einfachen Fall:
SELECT $f$SELECT * FROM crosstab(
$$SELECT DISTINCT ON (1, 2)
'max' AS "type", data_type, val
FROM tbl
ORDER BY 1, 2, val DESC$$
,$$VALUES ($f$ || string_agg(quote_literal(data_type), '), (') || $f$)$$)
AS x ("type" text, $f$ || string_agg(quote_ident(data_type), ' int, ') || ' int)'
FROM (SELECT DISTINCT data_type FROM tbl) x
Dadurch wird die Abfrage generiert, die Sie tatsächlich benötigen. Führen Sie die zweite in derselben Transaktion aus um Parallelitätsprobleme zu vermeiden.
Beachten Sie die strategische Verwendung von quote_literal()
und quote_ident()
um alle Arten illegaler (für Spalten) Namen zu bereinigen und SQL-Einschleusung zu verhindern .
Lassen Sie sich nicht durch mehrere Ebenen von Dollarnotierungen verwirren. Das ist notwendig, um dynamische Abfragen zu erstellen. Ich drücke es so einfach wie möglich aus.