Я думал о том, как решить эту проблему без использования циклов или курсоров, и я думаю, что у меня есть способ, но у меня возникают проблемы с его кодированием.
У меня есть таблица, в которой строки транзакций сгруппированы по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
Что мне нужно сделать, это получить дату последней действительной транзакции, то есть транзакции, которая НЕ была сторнирована, то есть TxnCode51. Так, например, в приведенных выше выборочных данных для счета 80780245 последняя TxnDate будет 71 тксн 6/6/2015, так как 51 тксн 12/22 отменяет 143,71 тн $ 16.11.2015 и 51 тксн.TXN 6/6/2015 отменяет 143,71 TXN 10/23.
Для Acctnumber 71627499 последняя дата TXN будет 3/10/2015 для 325 $ Txn.51 txn на 4/10 меняет 1 txn на 4/3
Для 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 ткснам и суммировать их при построении таблицы?Еще одна проблема, с которой у меня возникли проблемы с последним случаем выше, где первые 2 txn равны 51, тогда мне нужно было бы добавить эти 2 и 51Total будет иметь сумму этих значений, а SUM1 будет иметь значение первых 01 или 71 txn, чтобыло бы RN = 3.
Я использую этот код, но я не уверен, как получить сумму sum1 и следующее значение 1 1 или 71 в sum2.Кроме того, как справиться со сценарием, когда есть 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
Я открыт для любого другого решения, которое могут сделать большие умыпомоги мне подумать
Любая помощь очень ценится!