1

我有一个包含 3 列 rcvr_id(user 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 的 tpv 为 0。即,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=1347 月的 tpv- 1346 月的 tpv(即使两行都不存在,我必须将它们的 tpvs 设为 0)。对于 1346,tpv 将 = 1346 的 tpv-1345 的 tpv=-2。

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

详细信息:Teradata,超过百万行。我如何做到并高效地做到这一点。

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

4

1 回答 1

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
于 2012-08-27T13:56:37.373 回答