【问题标题】:SQL - How to SELECT the best two months which are next to each otherSQL - 如何选择相邻的最佳两个月
【发布时间】:2019-11-25 12:13:22
【问题描述】:
如何在PostgreSQL中select最好的两个月从Table。
Table:
ID Month Value
1 2019-06 100
2 2019-07 120
3 2019-08 70
4 2019-09 200
5 2019-10 100
6 2019-11 50
我想选择相邻的两个月的 sum(Value) 最高的 ID。
在以下情况下,结果将是:
4 2019-09
5 2019-10
其中值的总和等于300。
【问题讨论】:
标签:
sql
postgresql
select
【解决方案1】:
您可以使用join 将数据放在一行中:
select t1.*, t2.*
from t t1 join
t t2
on t2.month = t1.month + interval '1 month'
order by t1.value + t.value desc
limit 1;
获取单独的行比较棘手。您可以使用lead() 轻松获取第一行:
select t.*
from (select t.*, lead(value, 1, 0) over (order by month) as next_value
from t
) t
order by (value + next_value) desc
limit 1;
获得第二个月要困难得多。我认为最简单的方法是取消透视第一个结果:
select t.*
from (select t1, t2
from t t1 join
t t2
on t2.month = t1.month + interval '1 month'
order by t1.value + t.value desc
limit 1
) cross join lateral
unnest(array[t1, t2]) t
order by t.month;
【解决方案2】:
这是一个仅使用窗口函数的解决方案,它不假定month 是类似date 的数据类型。
它的工作原理如下:
查询:
select id, month, value
from (
select t.*, first_value(rn) over(order by rnk) rn_max
from (
select t.*, rank() over(order by vals desc) rnk
from (
select
t.*,
value + lag(value, 1, 0) over (order by month) vals,
row_number() over(order by month) rn
from mytable t
) t
) t
) t
where rn in (rn_max, rn_max - 1)
order by month
Step-by-step demo on DB Fiddle:
编号 |月 |价值
-: | :-------- | ----:
4 | 2019-09 | 200
5 | 2019-10 | 100