使用交叉表功能旋转 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;
我做了这个查询,列出了一个城市每年每平方米的所有房地产价格。它运作良好,但所有年份最终都排成一排,价格落后。我更愿意在单元格中看到列中的年份和价格。通过 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;