Още веднъж, за повече от само няколко "типове данни", предлагам да използвате 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)
Връща:
type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max | 500 | 1500 | 1200
Още обяснение за основите:
PostgreSQL Crosstab Query
Динамично решение
Трудното е да направите това напълно динамично :за да работи за
- неизвестен номер от колони (в този случай типове_данни)
- с неизвестни имена (отново типове_данни)
Поне тип е добре известно:integer
в този случай.
Накратко:това не е възможно с текущия PostgreSQL (включително 9.3). Има приближения с полиморфни типове и начини за заобикаляне на ограниченията с масиви или типове hstore. Може да е достатъчно добро за вас. Но това категорично не е възможно за да получите резултата с отделни колони в една SQL заявка. SQL е много твърд по отношение на типовете и иска да знае какво да очаква обратно.
Въпреки това , може да се направи с два запитвания. Първият изгражда действителната заявка за използване. Въз основа на горния прост случай:
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
Това генерира заявката, от която всъщност се нуждаете. Изпълнете втория в същата транзакция за да избегнете проблеми с едновременността.
Обърнете внимание на стратегическото използване на quote_literal()
и quote_ident()
за дезинфекция на всички видове незаконни (за колони) имена и предотвратяване на SQL инжектиране .
Не се обърквайте от няколко слоя цитиране на долари. Това е необходимо за изграждане на динамични заявки. Казах го възможно най-просто.