使用交叉表功能旋转 SQL table

Pivoting SQL table with crosstab function

我做了这个查询,列出了一个城市每年每平方米的所有房地产价格。它运作良好,但所有年份最终都排成一排,价格落后。我更愿意在单元格中看到列中的年份和价格。通过 Whosebug,我找到了 crosstab 函数并对其进行了试验。不幸的是,我似乎无法让它发挥作用。如果有人可以查看查询,我会很高兴。

查询输出示例

city        year    avg_price_m2
Amsterdam   2016    4407,51
Amsterdam   2017    5015,75
Amsterdam   2018    5648,1
Amsterdam   2019    5904,91

想要

city        2016    2017      2018    2019
Amsterdam   4407,51 5015,75   5648,1  5904,91

当前查询

SELECT city, 
       Extract(year FROM ondertekening_akte) AS year, 
       Round(Avg(transactieprijs_per_m2), 2) AS avg_price_m2 
FROM   transactiedata.transacties 
       JOIN bagactueel.gemeente 
         ON St_contains (bagactueel.gemeente.geovlak, 
            transactiedata.transacties.geopunt) 
WHERE  city = 'Amsterdam' 
       AND Extract(year FROM ondertekening_akte) > 2006 
GROUP  BY city, 
          year; 

旋转尝试

select * from crosstab (
    $$select city,
    extract(year from ondertekening_akte) as year,
    ROUND(AVG(transactieprijs_per_m2),2) as avg_price_m2
    from transactiedata.transacties
    JOIN bagactueel.gemeente ON ST_Contains (bagactueel.gemeente.geovlak, transactiedata.transacties.geopunt)
    where city = 'Amsterdam'
    and extract(year from ondertekening_akte) > 2006
    group by city, year$$,

    $$select distinct extract(year from ondertekening_akte) as year from transactiedata.transacties order by year$$

)
AS (
    "city" text,
    "2007" int,
    "2008" int,
    "2009" int,
    "2010" int,
    "2011" int,
    "2012" int,
    "2013" int,
    "2014" int,
    "2015" int,
    "2016" int,
    "2017" int,
    "2018" int,
    "2019" int
)
;

我收到这个错误:

ERROR:  invalid return type
DETAIL:  Query-specified return tuple has 14 columns but crosstab returns 17.

我知道如何在 SQL 服务器中进行 PIVOT,但我很确定 Crosstab 和 MSSQL 共享相同的 PIVOT 语法。由于我没有任何方法可以测试它,你可以试试这个代码吗?

    select City, [2011],[2012],[2013],[2014]
    from transactiedata.transacties
    JOIN bagactueel.gemeente ON ST_Contains (bagactueel.gemeente.geovlak, transactiedata.transacties.geopunt)
    where city = 'Amsterdam'
    and extract(year from ondertekening_akte) > 2006
PIVOT(ROUND(AVG(transactieprijs_per_m2),2)
     FOR YEAR IN ([2011],[2012],[2013],[2014])

第二个查询在crosstab()returns超过13行(正好16行)。您可能应该添加条件:

select distinct extract(year from ondertekening_akte) as year 
from transactiedata.transacties 
where extract(year from ondertekening_akte) > 2006 --!!
order by year

SQL 不是为这样的事情设计的,但如果我真的必须这样做,我通常更喜欢条件聚合而不是试图对抗 crosstab() 函数:

select city,
       ROUND(AVG(transactieprijs_per_m2),2) filter (where extract(year from ondertekening_akte) = 2007) as "2007",
       ROUND(AVG(transactieprijs_per_m2),2) filter (where extract(year from ondertekening_akte) = 2008) as "2008",
       ROUND(AVG(transactieprijs_per_m2),2) filter (where extract(year from ondertekening_akte) = 2009) as "2009",
       ROUND(AVG(transactieprijs_per_m2),2) filter (where extract(year from ondertekening_akte) = 2010) as "2010",
       ... and so on ...
from transactiedata.transacties
   JOIN bagactueel.gemeente ON ST_Contains (bagactueel.gemeente.geovlak, transactiedata.transacties.geopunt)
where city = 'Amsterdam'
  and extract(year from ondertekening_akte) > 2006
group by city;