Avi*_*hai 16 sql database postgresql crosstab aggregate-functions
假设我在Postgres中有一个表listings,看起来像这样:
id neighborhood bedrooms price
1 downtown 0 256888
2 downtown 1 334000
3 riverview 1 505000
etc.
Run Code Online (Sandbox Code Playgroud)
如何编写交叉表查询,将每间卧室的平均价格显示为列和邻域作为行?
查询的输出应该类似于这样(数字组成,列是卧室):
0 1 2 3
riverton 250000 300000 350000 -
downtown 189000 325000 - 450000
Run Code Online (Sandbox Code Playgroud)
小智 25
另一种使用过滤器实现的解决方案:
SELECT neighborhood,
avg(price) FILTER (WHERE bedrooms = 0) AS "0",
avg(price) FILTER (WHERE bedrooms = 1) AS "1",
avg(price) FILTER (WHERE bedrooms = 2) AS "2",
avg(price) FILTER (WHERE bedrooms = 3) AS "3"
FROM listings
GROUP BY neighborhood;
Run Code Online (Sandbox Code Playgroud)
Erw*_*ter 23
首先使用聚合函数avg()计算平均值:
SELECT neighborhood, bedrooms, avg(price)
FROM listings
GROUP BY 1,2
ORDER BY 1,2
Run Code Online (Sandbox Code Playgroud)
然后crosstab()按照相关答案中的详细说明将结果提供给函数:
小智 12
在 Postgres 中构建数据透视表的最佳方法是 CASE 表达式。
SELECT neighborhood,
round(avg((CASE WHEN bedrooms = 0 THEN price END)), 2) AS "0",
round(avg((CASE WHEN bedrooms = 1 THEN price END)), 2) AS "1",
round(avg((CASE WHEN bedrooms = 2 THEN price END)), 2) AS "2",
round(avg((CASE WHEN bedrooms = 3 THEN price END)), 2) AS "3"
FROM listings
GROUP BY neighborhood;
Run Code Online (Sandbox Code Playgroud)
在问题数据上运行这个会产生
NEIGHBORHOOD 0 1 2 3
-------------------- ---------- ---------- ---------- ----------
downtown 256888 334000 NULL NULL
riverview NULL 505000 NULL NULL
Run Code Online (Sandbox Code Playgroud)