Sql 与行上的滞后/超前合并?
嘿,伙计们,假设我有一个数据框Sql 与行上的滞后/超前合并?,sql,postgresql,Sql,Postgresql,嘿,伙计们,假设我有一个数据框 Year Month 1_month_sub 3_month_sub 12_month_sub 2014 1 3 1 1 2014 2 1 0 0 2014 3 1 0 0 2014
Year Month 1_month_sub 3_month_sub 12_month_sub
2014 1 3 1 1
2014 2 1 0 0
2014 3 1 0 0
2014 4 1 0 0
2014 5 4 0 0
2014 6 1 0 0
2014 7 5 0 0
2014 8 1 0 0
2014 9 1 0 0
2014 10 6 0 0
2014 11 1 0 0
2014 12 3 0 0
其中1个月sub表示购买了1个月的订阅,3个月sub表示购买了3个月的订阅等。
我需要添加一个专栏,让我在任何给定的时间单位每月订阅一次。因此,结果如下所示:
Year Month 1_month_sub 3_month_sub 12_month_sub subs
2014 1 3 1 1 5
2014 2 1 0 0 3
2014 3 1 0 0 3
2014 4 1 0 0 2
2014 5 4 0 0 5
2014 6 1 0 0 2
2014 7 5 0 0 6
2014 8 1 0 0 2
2014 9 1 0 0 2
2014 10 6 0 0 7
2014 11 1 0 0 2
2014 12 3 0 0 4
2015 1 1 0 0 1
我使用了联合、滞后、超前功能,但没有取得真正的成功。有什么办法吗?你试过类似的方法吗 编辑:@Gordon Linoff下面的答案更好-相同的想法,但将前3个和前12个值封装在单个表达式中
select subs=(1_month_sub) +
lag(3_month_sub, 2, 0) over (order by Year, Month) +
lag(3_month_sub, 1, 0) over (order by Year, Month) +
3_month_sub +
lag(12_month_sub, 11, 0) over (order by Year, Month) +
lag(12_month_sub, 10, 0) over (order by Year, Month) +
lag(12_month_sub, 9, 0) over (order by Year, Month) +
lag(12_month_sub, 8, 0) over (order by Year, Month) +
lag(12_month_sub, 7, 0) over (order by Year, Month) +
lag(12_month_sub, 6, 0) over (order by Year, Month) +
lag(12_month_sub, 5, 0) over (order by Year, Month) +
lag(12_month_sub, 4, 0) over (order by Year, Month) +
lag(12_month_sub, 3, 0) over (order by Year, Month) +
lag(12_month_sub, 2, 0) over (order by Year, Month) +
lag(12_month_sub, 1, 0) over (order by Year, Month) +
12_month_sub
from MyTable
我推测数据在一个表格中,1个月的SUB只存在1个月,3个月的SUB存在3个月,12个月的SUB存在12个月 此外,我将假设每个月都有一个连续 您可以在Postgres中使用累积和上的窗口子句执行此操作:
select t.*,
(1_month_sub +
sum(3_month_sub) over (order by year rows between 2 preceding and current row) +
sum(12_month_sub) over (order by year rows between 11 preceding and current row)
) as total_subs
from t;
没有电源功能也可以做到这一点。下面已经在PostgreSQL和MS SQL上进行了测试 请参见SQL FIDLE的工作原理: 简单SQL连接
select
t1.Year,
t1.Month,
sum(case when ((t2.Year-2014)*12+t2.Month) <= ((t1.Year-2014)*12+t1.Month) and ((t2.Year-2014)*12+t2.Month) - ((t1.Year-2014)*12+t1.Month) > -1 then 1 else 0 end * t2.one_ms) +
sum( case when ((t2.Year-2014)*12+t2.Month) <= ((t1.Year-2014)*12+t1.Month) and ((t2.Year-2014)*12+t2.Month) - ((t1.Year-2014)*12+t1.Month) > -3 then 1 else 0 end * t2.three_ms ) +
sum( case when ((t2.Year-2014)*12+t2.Month) <= ((t1.Year-2014)*12+t1.Month) and ((t2.Year-2014)*12+t2.Month) - ((t1.Year-2014)*12+t1.Month) > -12 then 1 else 0 end * t2.twelve_ms ) as subs
from Test t1
join Test t2
on 1=1
group by t1.Year, t1.Month, ((t1.Year-2014)*12+t1.Month)
order by ((t1.Year-2014)*12+t1.Month)
工作:
为了更好地理解它,您可能需要为t1.Year-2014*12+t1.Month指定一个别名,例如num:
你能解释一下输出中SUB列的计算吗?Postgres实际上没有dataframe的概念。这些信息在表格中吗?对不起,我已经习惯了R,所以我把所有的东西都称为数据帧。是的,我的意思是桌子。你错过了12个月sub的滞后1;我做了类似的事情,但我同时使用了分区和覆盖。“我会让这一点运行一点,”戈登林诺夫-谢谢,你的答案是更好的一个无论如何;这很有魅力。我是一个新的窗口条款的大风扇-它已经派上用场几次了。
1 2 3 4 5
+---------+
1|O . . . .|
2|O O . . .|
3|O O O . .|
4|. O O O .|
5|. . O O O|
+---------+
year month subs
2014 1 5
2014 2 3
2014 3 3
2014 4 2
2014 5 5
2014 6 2
2014 7 6
2014 8 2
2014 9 2
2014 10 7
2014 11 2
2014 12 4
2015 1 1
alter table Test add column num int NULL
update Test
set num = (Year-2014)*12+Month
select
t1.Year,
t1.Month,
sum(case when t2.num <= t1.num and t2.num - t1.num > -1 then 1 else 0 end * t2.one_ms) +
sum( case when t2.num <= t1.num and t2.num - t1.num > -3 then 1 else 0 end * t2.three_ms ) +
sum( case when t2.num <= t1.num and t2.num - t1.num > -12 then 1 else 0 end * t2.twelve_ms ) as subs
from Test t1
join Test t2
on 1=1
group by t1.Year, t1.Month, t1.num
order by t1.num