【问题标题】: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

【问题讨论】:

  • 彼此相邻表示连续的id还是连续的月份?

标签: 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 的数据类型。

    它的工作原理如下:

    • 使用row_number()(别名为rn)对每个递增月份的记录进行排名并计算当前值和先前值的总和(别名为vals

    • vals(别名rnk)对记录进行排名

    • 显示行号最高的记录vals(别名rn_max

    • 最后拉出这条记录和前面的记录(即有前行号的记录)

    查询:

    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

    【讨论】:

      猜你喜欢
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      相关资源
      最近更新 更多