【问题标题】:How to divide between rows in one table in Postgres如何在 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;

【问题讨论】:

    标签: sql postgresql


    【解决方案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;
        

        【讨论】:

          猜你喜欢
          • 2016-09-23
          • 2020-07-20
          • 1970-01-01
          • 2019-10-16
          • 1970-01-01
          • 2018-03-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多