Nogmaals, voor meer dan alleen een paar "gegevenstypen", raad ik aan om crosstab()
te gebruiken :
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)
Retourneren:
type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max | 500 | 1500 | 1200
Meer uitleg voor de basis:
PostgreSQL Crosstab Query
Dynamische oplossing
Het lastige is om dit volledig dynamisch te maken :om het te laten werken voor
- een onbekend nummer van kolommen (data_types in dit geval)
- met onbekende namen (nogmaals data_types)
Tenminste het type is bekend:integer
in dit geval.
Kortom:dat kan niet met het huidige PostgreSQL (inclusief 9.3). Er zijn benaderingen met polymorfe typen en manieren om de beperkingen met arrays of hstore-typen te omzeilen. Misschien goed genoeg voor je. Maar het is strikt niet mogelijk om het resultaat met afzonderlijke kolommen in een enkele SQL-query te krijgen. SQL is erg rigide over typen en wil weten wat ze terug kunnen verwachten.
Echter , het kan met twee vragen. De eerste bouwt de eigenlijke query die moet worden gebruikt. Voortbouwend op het bovenstaande eenvoudige geval:
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
Dit genereert de query die u daadwerkelijk nodig heeft. Voer de tweede uit binnen de dezelfde transactie om gelijktijdigheidsproblemen te voorkomen.
Let op het strategische gebruik van quote_literal()
en quote_ident()
om allerlei illegale (voor kolommen) namen te zuiveren en SQL-injectie te voorkomen .
Raak niet in de war door meerdere lagen dollarcitaten. Dat is nodig voor het bouwen van dynamische queries. Ik heb het zo eenvoudig mogelijk gesteld.