根据帐户交易分组进行循环

时间:2018-10-02 22:51:09

标签: sql loops tsql cursor

我一直在考虑如何在不使用循环或游标的情况下解决此问题,我想我有办法,但是在编码时遇到了问题。

我有一个表,其中有按acctnumbers(RN是行号或每个帐户分区)分组的交易行,例如:

INSERT INTO REVERSAL_TEST (AcctNumber, TxnDate, TxnCode, TxnAmount, RN)
VALUES('80780245',  2015-12-22,   51,   143.71,           1),
    ('80780245',    2015-11-16, 1,  -143.71,          2),
    ('80780245',    2015-11-6,  51, 143.71,         3),
    ('80780245',    2015-11-6,  71, -33.44,           4),
    ('80780245',    2015-10-23, 1,  -143.71,          5),
    ('80780245',    2015-9-17,  1,  -143.71,         6),
    ('80780245',    2015-8-11,  1,  -143.71,          7),
    ('71627499',    2015-4-10,  51, 315,              1),
    ('71627499',    2015-4-3,   1,  -315,             2),
    ('71627499',    2015-3-10,  1,  -325,             3),
    ('71627499',    2015-3-10,  51, 325,              4),
    ('71627499',    2015-3-10,  51, 325,              5),
    ('71627499',    2015-3-4,   1,  -325,             6),
    ('71627499',    2015-2-10,  51, 325,              7),
    ('71627499',    2015-2-3,   1,  -325,             8),
    ('71627499',    2015-1-31,  51, 315,              9),
    ('71627499',    2015-1-14,  1,  -315,             10),
    ('71627499',    2014-12-9,  51, 325,              11),
    ('71627499',    2014-12-5,  1,  -325,             12),
    ('82345872',    2016-8-17,  51, 716.58,           1),
    ('82345872',    2016-8-5,   1,  -238.86,          2),
    ('82345872',    2016-7-28,  71, -477.72,          3),
    ('83495429',    2018-08-20, 51, 600.00,         1),
    ('83495429',    2018-08-20, 51, 600.00,         2),
    ('83495429',    2018-08-20, 71, -600.00,         3),
    ('83495429',    2018-08-17, 1,  -200.00,        4),
    ('83495429',    2018-07-20, 1,  -200.00,         5),
    ('83495429',    2018-06-25, 1,  -200.00,         6);





    AcctNumber  TxnDate       TxnCode   TxnAmount   RN
    80780245    12/22/2015 0:00 51  143.71           1
    80780245    11/16/2015 0:00 1   -143.71          2
    80780245    11/6/2015 0:00  51  143.71           3
    80780245    11/6/2015 0:00  71  -33.44           4
    80780245    10/23/2015 0:00 1   -143.71          5
    80780245    9/17/2015 0:00  1   -143.71          6
    80780245    8/11/2015 0:00  1   -143.71          7
    71627499    4/10/2015 0:00  51  315              1
    71627499    4/3/2015 0:00   1   -315             2
    71627499    3/10/2015 0:00  1   -325             3
    71627499    3/10/2015 0:00  51  325              4
    71627499    3/10/2015 0:00  51  325              5
    71627499    3/4/2015 0:00   1   -325             6
    71627499    2/10/2015 0:00  51  325              7
    71627499    2/3/2015 0:00   1   -325             8
    71627499    1/31/2015 0:00  51  315              9
    71627499    1/14/2015 0:00  1   -315             10
    71627499    12/9/2014 0:00  51  325              11
    71627499    12/5/2014 0:00  1   -325             12
    82345872    8/17/2016 0:00  51  716.58           1
    82345872    8/5/2016 0:00   1   -238.86          2
    82345872    7/28/2016 0:00  71  -477.72          3
    83495429    2018-08-20 00:00:00 51  600.00       1
    83495429    2018-08-20 00:00:00 51  600.00       2
    83495429    2018-08-20 00:00:00 71  -600.00      3
    83495429    2018-08-17 00:00:00 01  -200.00      4
    83495429    2018-07-20 00:00:00 01  -200.00      5
    83495429    2018-06-25 00:00:00 01  -200.00      6

我需要做的是获取上一次有效交易的日期,该交易是尚未撤销的交易,即TxnCode 51。 因此,例如,在上述示例数据中,帐户80780245的最后一个TxnDate将是11/6/2015的71 txn,因为12/22的51 txn反转了2015年11月16日的143.71 txn和2015年11月16日的51 txn 2015年11月6日在10/23反转了143.71 txn。

对于Acctnumber 71627499,最后的日期为2015年3月3日,价格为325美元。 4/10上的51 txn反转4/3上的1 txn

对于AcctNumber 82345872 51,它会反转下一个1和71的总和,因此最后一个txn日期为NULL

对于AcctNumber 83495429,前2个txns为51,因此将其添加到51总数中,并反转1和71的总和,因此最后一个txn日期为NULL

 Sample output:
80780245    11/6/2015
71627499    3/10/2015
82345872    NULL
83495429    NULL

我知道可能会有很多极端情况,确切的规格非常模糊,就像我正在从事的现实世界项目一样。

我考虑过使用游标或while循环,但是我正在使用许多帐户,因此不确定运行是否可行,因为性能太糟糕了。

我正在考虑使用以下架构创建临时表/视图:

    AcctNumber 51Total  Sum1 Sum2 Sum3 Sum4......

其中51Total是51个txn的总和,而sum1是txn的第一个值,其中txncode是1或71,sum2是sum1的值之和+ txncode的下一个值1或71,等等。  然后,我可以遍历一下,看看哪个sumX将使51Total净额化,这就是要获取txn日期的txn的数量。 这应该比使用while循环或游标更快,但是,我在编码时遇到了问题。 有人可以帮助我如何访问前1个和71个txns并在建立表时对其求和吗? 我遇到的另一个问题是上面的最后一个情况,前两个txn为51,那么我需要将这两个2和51相加,总计将具有这些值的总和,而SUM1将具有前一个01或71 txn的值,会是RN = 3。

我正在使用此代码,但不确定如何获取sum1和sum2中的下一个1 1或71值之和。另外,当我需要对2 51个txn进行求和,然后才能得出将51值作为净值的总和时,该如何处理呢?

    SELECT 
         r.AcctNumber
        ,MAX(CASE WHEN r.RN = 1 THEN r.TxnAmount ELSE NULL END) AS '51Total'
        ,MAX(CASE WHEN r.RN = 2 AND r.TxnCode <> '51' THEN r.TxnAmount ELSE NULL END) AS 'SUM1'
        ,MAX(CASE WHEN r.RN = 3 AND r.TxnCode <> '51' THEN r.TxnAmount ELSE NULL END) AS 'SUM2'
    FROM #ReversalAccountTxnDetails r
    GROUP BY r.AcctNumber

我愿意接受任何其他解决方案,大胆的想法可以帮助我思考。

非常感谢您的帮助!

0 个答案:

没有答案