使用PostgreSQL创建一个数据透视表

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()按照相关答案中的详细说明将结果提供给函数:

  • @Avishai :(全功能)语法简写,带位置参考,简称"GROUP BY邻居,卧室" (6认同)

小智 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)