按月分类月份

时间:2014-05-28 18:29:12

标签: sql postgresql row-number

假设我有2年的数据。 2010年1月至2011年12月。
我想将每个月份分类为期间。所以2010年1月将是​​我的1,2010年2月我的2,依此类推,直到2011年12月我的24期。

我知道我可以这样做:

select 
    year,mn, 
    case when year=2010 and mn=01 then 1
    else when year=2010 and mn=02 then 2
    else when year=2010 and mn=03 then 3
    //and so on until // else when year=2011 and mn=12 then 24 end 
from mytable;

结果如下:

year    mn  period
2010    1   1
2010    2   2
2010    3   3
2010    4   4
2010    5   5
2010    6   6
2010    7   7
2010    8   8
2010    9   9
2010    10  10
2010    11  11
2010    12  12
2011    1   13
2011    2   14
2011    3   15
2011    4   16
2011    5   17
2011    6   18
2011    7   19
2011    8   20
2011    9   21
2011    10  22
2011    11  23
2011    12  24

我想避免这种长期而不明智的方法。

3 个答案:

答案 0 :(得分:1)

select
    year, mn,
    row_number() over (order by year, mn) as period
from t

答案 1 :(得分:1)

针对此特定案例的廉价版本:

SELECT year, mn, (year - 2010) * 12 + mn AS period
FROM   tbl;

这也可以说明数据中可能缺少的月数 即使只选择某些行,它也能为您提供一致的数字。

答案 2 :(得分:1)

不需要花哨的窗口功能。就这么简单。对于给定的{epoch-year}{epoch-month}(例如,分别为2010和1),公式

( ( 12*year + mn ) - ( 12*{epoch-year} + {epoch-month} )

将为您提供与纪元相同的月份偏移量。添加1,你有你的期间号码。这会导致你这样的事情:

select year ,
       mn   ,
       (   ( 12*year         + mn            )
         - ( 12*{epoch-year} + {epoch-month} )
       ) + 1 as period
       ...
from some-table
where   year > {epoch-year}
   OR ( year = {epoch-year} and mn >= {epoch-month} )

如果您没有特定的时代,您可以这样做:

select t.year ,
       t.mn   ,
       (   ( 12*year       + mn          )
         - ( 12*epoch.year + epoch.month )
       ) + 1 as period
       ...

from       ( select year,mn
             from some-table
             order by year , mn
             limit 1
           ) epoch
cross join some-table t

你应该注意到,人们可以根据超过1个月的周期长度来计算一个数字周期的公式:只计算几个月的偏移量,并使用整数除法将该偏移量除以周期长度(以月为单位),从而得到连续的期间数,如

       (   ( 12*year + mn )
         - ( 12*2010 + 1  )
       ) DIV 3 + 1 as period

应该给你3个月的时间