Время прочтения: 4 мин.
На просторах сети интернет достаточно примеров по поиску значения даты, предшествующей отчетной. Но я не встретил примеров, которые бы помогли определить дату, в частности дату проведения операции, которая может быть меньше на дни, месяцы, годы…
В рамках поставленной задачи необходимо было провести выборку остатков по счетам, на отчетную дату. Возьмем за дату отчета 01.02.2021 и один счет, на примере которого проведем все необходимые действия:
Проводим выборку всех имеющихся операций до отчетной даты:
SELECT
[Дата операции]
,[Время операции]
,[Сумма операции]
,[Баланс после операции]
,[Порядковый номер операции по счету]
FROM [Транзакции по картам]
where
[Номер счета] = '40817************74'
and [Дата операции] < '2021-02-01'
До отчетной даны у нас получилось 115 операций:
Для того, чтобы нам выбрать последнюю операцию с датой, предшествующей отчетной, можно использовать несколько функций, применимых к нашей выборке:
- Datediff – функция используется для вычисления разности двух дат;
- Оконная функция Over () в сочетании агрегатной функцией MAX (), используемой для поиска максимального значения определенного столбца или выражения.
Итак, рассмотрим действие функции Datediff, с помощью которой мы найдем разницу в днях между отчетной датой и датой проведенной операции. Чем меньше значение, тем больше такая операция нам подходит:
SELECT
[Дата операции]
,datediff (day,[Дата операции],'2021-02-01') As [Разница в днях]
,[Время операции]
,[Сумма операции]
,[Баланс после операции]
,[Порядковый номер операции по счету]
FROM [Транзакции по картам]
where
[Номер счета] = '40817************74'
and [Дата операции] < '2021-02-01'
Мы видим, что наименьшая разница у нас отражена за 30.01.2021. Однако возникает проблема с определением необходимой операции, т.к. за данное число было проведено две операции, и соответственно указано два остатка.
Соответственно использовать только функцию datediff
мы не можем.
И к нам на помощь при ходит оконная функция Over ()
в сочетании агрегатной функцией MAX ()
, которые мы применим к двум столбцам [Время операции] и [Порядковый номер операции по счету], позволяющим придать точности нашему запросу:
SELECT
[Дата операции]
,datediff (day,[Дата операции],'2021-02-01') As [Разница в днях]
,[Время операции]
,max([Время операции]) over (partition by [Номер счета]) As [Время операции_max]
,[Сумма операции]
,[Баланс после операции]
,[Порядковый номер операции по счету]
,max([Порядковый номер операции по счету]) over (partition by [Номер счета])
As [Номер операции_max]
FROM [Транзакции по картам]
where
[Номер счета] = '40817************74'
and [Дата операции] < '2021-02-01'
Для вывода искомого значения наш запрос обернем в подзапрос с применением дополнительных условий:
select s.*
from
(SELECT
[Дата операции]
,datediff (day,[Дата операции],'2021-02-01') As [Разница в днях]
,[Время операции]
,max([Время операции]) over (partition by [Номер счета]) As [Время операции_max]
,[Сумма операции]
,[Баланс после операции]
,[Порядковый номер операции по счету]
,max([Порядковый номер операции по счету]) over (partition by [Номер счета])
As [Номер операции_max]
FROM [Транзакции по картам]
where
[Номер счета] = '40817************74'
and [Дата операции] < '2021-02-01'
) S
where S.[Номер операции_max] = S.[Порядковый номер операции по счету]
and S.[Время операции_max] = S.[Время операции]
Вот так данные команды помогут нам в определении баланса по транзакционным операциям, проведенным до отчетной даты.