У меня есть таблица (в SQL Server 2014), включающая несколько промежуточных итогов (по разным датам) - не идеальный дизайн, но представьте себе очень большое количество строк и пользователей, способных выбрать определенный период времени - нам не нужно вычислять суммы с начала времени, чтобы каждый раз получать промежуточную сумму за этот период.
Я ищу элегантный способ обновить эти промежуточные итоги при обновлении нескольких строк.
Фактический сценарий - сверка счетов - в таблице хранятся денежные операции, для которых у нас есть дата события (например, когда вещь была продана), дата транзакции (например, дата счета-фактуры) и дата платежа (когда счет был оплачивается). Для каждого из них есть промежуточный итог, например, (значительно упрощено)
CREATE TABLE MyTransaction (
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
EventDate DATETIME NOT NULL,
TransactionDate DATETIME,
PaymentDate DATETIME,
Amount INT, -- assume whole numbers for sake of it
RunningTotalByEventDate INT,
RunningTotalByTransactionDate INT,
RunningTotalByPaymentDate INT,
IsCancelled BIT DEFAULT (0)
)
... с указанием даты по мере необходимости и т. Д. И для примера предположим, что дата / время уникальны (на практике существуют уникальные и другие элементы).
Вставка транзакции - это хорошо (иш) - лучше всего я придумал три отдельных запроса, каждый из которых обновляет промежуточную сумму на соответствующую дату ... или один запрос с логикой ... поэтому после вставки новой строки ( с явно названными переменными, передаваемыми в не сохраненный процесс) ...
UPDATE MyTransaction SET RunningTotalByEventDate += @Amount
WHERE EventDate > @EventDate
и т. Д. Для двух других промежуточных итогов или одного запроса, например ...
UPDATE MyTransaction
SET RunningTotalByEventDate += CASE WHEN EventDate > @EventDate THEN @Amount ELSE 0 END,
RunningTotalByTransactionDate += CASE WHEN TransactionDate > @TransactionDate THEN @Amount ELSE 0 END,
RunningTotalByPaymentDate += CASE WHEN PaymentDate > @PaymentDate THEN @Amount ELSE 0 END
WHERE EventDate > @EventDate
OR TransactionDate > @TransactionDate
OR PaymentDate > @PaymentDate
Теперь мне нужно отменить транзакции, например, Счет-фактура списывается - необходимо оставить строку, но удалить эффект, чтобы строка оставалась со своей суммой, но установлен флаг отмены и строка не влияет на промежуточные итоги. К сожалению, в счете может быть несколько транзакций (например, несколько платежей по частям), поэтому может быть несколько строк транзакций для обновления.
Мой лучший вариант для обновления нескольких промежуточных итогов на данный момент - это зацикливание / наведение курсора на (как ожидается, будет несколько) обновленных строк и уменьшение последующих промежуточных итогов по мере того, как мы увеличивали их при добавлении строки - так для каждого раза В цикле у нас есть три запроса на обновление (или один с логикой) для обновления трех текущих итогов.
Одно ОБНОВЛЕНИЕ не будет работать, так как оно будет обновлять целевую строку только один раз (и если две частичные выплаты отменяются, нам нужно обновить его дважды, чтобы снять каждую сумму). Я по-разному играл с оконными функциями, но не вижу способа сделать это аккуратно с помощью одного запроса.
Итак, учитывая список MyTransaction.Id
значений для отмены (например, в таблице, табличной переменной или списке строк CSV), каков наилучший способ обновить различные промежуточные итоги?
Любые идеи (и извинения за бессвязный вопрос) приветствуются.