Классификация месяцев по периодам
Предположим, у меня есть данные за 2 года. С января 2010 года по декабрь 2011 года.
Я хочу классифицировать каждый месяц как период. Таким образом, январь 2010 будет моим 1, февраль 2010 моим 2, и так далее до декабря 2011 года мой 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 ответа
select
year, mn,
row_number() over (order by year, mn) as period
from t
Дешевая версия для этого конкретного случая:
SELECT year, mn, (year - 2010) * 12 + mn AS period
FROM tbl;
Это также будет учитывать месяцы, которые могут отсутствовать в ваших данных.
И это даст вам согласованные числа, даже если выбрать только несколько строк.
Нет необходимости в модных оконных функциях. Просто сделай это простым способом. Для данного {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 месяца