use*_*933 2 sql postgresql pivot crosstab
我有一个表,其数据看起来像这样:
data_type, value
World of Warcraft, 500
Quake 3, 1500
Quake 3, 1400
World of Warcraft, 1200
Final Fantasy, 100
Final Fantasy, 500
Run Code Online (Sandbox Code Playgroud)
我想要做的是在一个语句中选择每个值的最大值.我知道我可以轻松做点什么
select data_type, max(value)
from table
where data_type = [insert each data type here for separate queries]
group by data_type
Run Code Online (Sandbox Code Playgroud)
但我希望它显示的是
select data_type,
max(value) as 'World of Warcraft',
max(value) as 'Quake 3',
max(value) as 'Final Fantasy'
Run Code Online (Sandbox Code Playgroud)
所以我在一个语句中得到每个的最大值.我该怎么做呢?
再一次,对于不止一些"数据类型",我建议使用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)
Run Code Online (Sandbox Code Playgroud)
返回:
type | Final Fantasy | Quake 3 | World of Warcraft
-----+---------------+---------+-------------------
max | 500 | 1500 | 1200
Run Code Online (Sandbox Code Playgroud)
更多基础知识解释:
PostgreSQL交叉表查询
棘手的是让它完全变得动态:让它发挥作用
至少这种类型是众所周知的: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
Run Code Online (Sandbox Code Playgroud)
这会生成您实际需要的查询.在同一事务中运行第二个以避免并发问题.
请注意策略性使用quote_literal()和quote_ident()清理各种非法(列)名称并防止SQL注入.
不要被多层美元引用混淆.这对于构建动态查询是必要的.我说它尽可能简单.
| 归档时间: |
|
| 查看次数: |
8638 次 |
| 最近记录: |