高效地迭代sql表
我有一个表,有3列rcvr_id(用户id)、mth_id和tpv。mth_id的计算公式为(2012-1900)*12+1,2,3(取决于是否为1月、2月、3月)。例如,2011年12月的mth_id为1344,2012年1月为1345。第三列是tpv,它是一个十进制数字,保存用户当月的交易。一个示例表是高效地迭代sql表,sql,loops,teradata,Sql,Loops,Teradata,我有一个表,有3列rcvr_id(用户id)、mth_id和tpv。mth_id的计算公式为(2012-1900)*12+1,2,3(取决于是否为1月、2月、3月)。例如,2011年12月的mth_id为1344,2012年1月为1345。第三列是tpv,它是一个十进制数字,保存用户当月的交易。一个示例表是 rcvr_id mth_id tpv . .
rcvr_id mth_id tpv
.
.
.
1 1326 23
1 1327 13
1 1329 9
1 1345 2
1 1330 25
1 1350 22
2 1325 31
2 1351 23
3 1327 130
3 1329 90
3 1345 20
3 1330 250
3 1350 220
.
.
.
对于其他用户(mth_id可能不会被订购)(rcvr_id和mth_id一起构成主键)。rcvr 2必须被忽略,因为他在1326和1350个月之间没有tpv
mth_id中缺少行值表示该月rcvr的tpv为0。
i、 e,13281331至13441346至1350 tpv为0
问题:我想创建一个表,其中包含两列rcvr_id、mth_id和第三列-change_。例如1327年的月份。。争吵会是这样的
1 1327 10,i.e (tpv of 1327-tpv of 1326)
对于用户1:
对于1347个月,tpv的变化=1347个月的tpv-1346个月的tpv(即使两行都不存在,我也必须将它们的tpv取为0)。对于1346年,tpv将=1346年的tpv,1345年的tpv=-2
对于每个接收者(tpv在1326和1350之间),我需要计算1327到1350个月tpv的变化
详细信息:Teradata,超过百万行。我如何做到这一点,以及如何高效地做到这一点
可以使用多个查询/临时表您可以通过简单的自连接来完成大部分操作:
select t.rcvr_id, t.mth_id, (t.tpv - coalesce(tprev.tpv, 0) as diff
from t left outer join
t tprev
on t.rcvr_id = tprev.rcvr_id and
t.mth_id = tprev.mth_id+1
要获得所有的月份,需要有一个驾驶台。假设你有一张月表,我称之为月:
select tm.rcvr_id, tm.mth_id, (coalesce(t.tpv, 0) - coalesce(tprev.tpv, 0) as diff
from (select distinct t.rcvr_id, m.mth_id
from t cross join
months m
) tm left outer join
t
on tm.rcvr_id = t.rcvr_id and
tm.mth_id = t.mth_id left outer join
t tprev
on t.rcvr_id = tprev.rcvr_id and
t.mth_id = tprev.mth_id+1
如果没有月参考表,可以动态创建月列表(假设每个月在原始表中至少存在一次):
sry用于这么多编辑:XYou已经为Oracle标记了这个,但是您在描述中说它是Teradata(并且它也被标记为Teradata)。甲骨文在哪里参与了这个过程?哦,是的,我的错。你想让我创建一个只有一列且值介于1326和1350之间的月表m吗?我必须使用你写的两种代码吗?@ganducoder。请尝试查询的第一个版本。它为原始表中的每一行返回一行。这听起来也像是你想要“填充”输出,包括表中没有的月份。如果是这样的话,你需要一种方法来度过这几个月。这就是第二个问题所暗示的。顺便说一句,我很惊讶,如果你有一个名为mth_id的列,你没有它的引用表。引用表不是问题,我可以单独创建它。假设我用一列mth_id制作一个表,其值从1326到1350。然后我运行你的两个代码。对的
select tm.rcvr_id, tm.mth_id, (coalesce(t.tpv, 0) - coalesce(tprev.tpv, 0) as diff
from (select r.rcvr_id, m.mth_id
from (select distinct t.rcvr_id from t) r cross join
(select distinct t.mth_id from t) m
) tm left outer join
t
on tm.rcvr_id = t.rcvr_id and
tm.mth_id = t.mth_id left outer join
t tprev
on t.rcvr_id = tprev.rcvr_id and
t.mth_id = tprev.mth_id+1