如何在 Postgres 中的一个表中的行之间进行划分
Posted
技术标签:
【中文标题】如何在 Postgres 中的一个表中的行之间进行划分【英文标题】:How to divide between rows in one table in Postgres 【发布时间】:2015-06-27 20:12:50 【问题描述】:我在 Postgres 中使用这样的表格:
mon yyyy weather
Apr 2014 78.45
Apr 2015 77.32
May 2014 79.56
May 2015 78.43
我希望能够查询一些按“mon”排序的结果,其中weather
列值按年按月划分。
换句话说,我想查询 2015 年 4 月除以 2014 年 4 月的天气。
但是,我想以不必指定月份或年份的方式编写查询,并且查询会根据以下情况自动划分 weather
值:2015 年 4 月/2014 年 4 月,然后是 2014 年 5 月/5 月2014年不用每个月、每年都输入,很费力。
我有以下代码,但这扩展了我不想要的列:
select (select "Weather" from yoy
where mon = 'Apr' and yyyy = '2015'
)/(select "American" from yoy
where mon = 'Apr' and yyyy = '2014'
) as "weather_apr",
(select "Weather" from yoy
where mon = 'May' and yyyy = '2015'
)/(select "Weather" from yoy
where mon = 'May' and yyyy = '2014'
) as "weather_may",
from yoy;
【问题讨论】:
【参考方案1】:在我看来,这是利用分析window function 的正确方案。这里是没有连接的魔法:
SELECT yyyy,
weather,
mon,
lead( weather ) over (partition by mon order by mon, yyyy desc),
weather / lead( weather ) over (partition by mon order by mon, yyyy desc)
FROM joy
【讨论】:
【参考方案2】:我认为您需要像下面的示例一样进行自我加入:
SELECT j1."yyyy" As year,
j2."yyyy" As next_year,
j1."mon",
j1."weather",
j2."weather" As "weather from next year",
j1."weather"::float / j2."weather" As divide
FROM joy j1
JOIN joy j2
ON j1."yyyy" = j2."yyyy" - 1 AND j1."mon" = j2."mon"
演示:http://sqlfiddle.com/#!15/e02ec/1
【讨论】:
【参考方案3】:我发现条件聚合对于这种类型的查询非常有用:
select mon,
max(case when yyyy = 2014 then weather end) as weather_2014,
max(case when yyyy = 2015 then weather end) as weather_2015,
(max(case when yyyy = 2015 then weather end) /
max(case when yyyy = 2014 then weather end)
) as ratio
from yoy
group by mon
这假设您希望将行数减少到每月一行。要获取之前的值,只需使用lag()
:
select yoy.*,
lag(weather) over (partition by month order by year) as prev_weather
from yoy;
【讨论】:
以上是关于如何在 Postgres 中的一个表中的行之间进行划分的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Postgres 中 CSV 文件中的值更新选定的行?