有效地遍历sql表

时间:2012-08-27 11:50:05

标签: sql loops teradata

我有一个包含3列rcvr_id(用户ID),mth_id和tpv的表。 mth_id计算为(2012-1900)* 12 + 1,2,3(取决于它是jan,feb,march)。例如,2011年12月的mth_id是1344,2012年1月是1345.第三列是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_ids)(rcvr_id和mth_id一起构成主键).Rcvr 2必须被忽略,因为他在1326和1350之间没有tpv。

mth_id中缺少的行值表示该月份的rcvr为0 tpv。 即,1328,1331至1344,1346至1350 tpv为0。

问题:我想创建一个表,其中包含两列rcvr_id,mth_id和第三列-change_in_tpv。例如,对于1327个月,该行就像

1        1327       10,i.e (tpv of 1327-tpv of 1326)

对于用户1 对于1347个月,更改tpv = tpv,即第1346个月的1347-tpv(即使两行都不存在,我也必须将他们的tpv设为0)。对于1346,tpv将是= tpv,1346-tpv,1345 = -2。

对于每个接收器(tpv在1326和1350之间),我需要计算13p到1350个月的tpv变化。

详细信息:Teradata,超过百万行。我怎么做,并且效率高。

可以使用多个查询/临时表

1 个答案:

答案 0 :(得分:2)

您可以通过简单的自我加入来完成大部分工作:

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

如果您没有月份参考表,您可以动态创建月份列表(假设每个月至少在原始表格中一次):

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