1

rcvr_id(user id)、mth_id、および tpv の 3 つの列を持つテーブルがあります。mth_id は (2012-1900)*12+1,2,3 (1 月、2 月、3 月のいずれかによる) として計算されます。たとえば、2011 年 12 月の mth_id は 1344、2012 年 1 月の mth_id は 1345 です。3 番目の列は tpv で、10 進数で、その月のユーザーのトランザクションを保持します。テーブルの例は次のとおりです。

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 であることを示しています。つまり、1328、1331 ~ 1344、1346 ~ 1350 tpv は 0 です。

問題: 2 つの列 rcvr_id,mth_id と 3 番目の列 -change_in_tpv を保持するテーブルを作成したいと考えています。たとえば、月 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、100 万行以上。どうすれば効率的に実行できますか。

複数のクエリ/一時テーブルを使用できます

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

月の参照テーブルがない場合は、その場で月のリストを作成できます (各月が少なくとも 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 に答える