Клиенту нужен инструмент, чтобы показать неудачные ежемесячные платежи клиентов несколько месяцев назад. Начальный месяц и количество месяцев назад должны быть определены пользователем
все платежи заносятся в одну таблицу.
Там могут быть или не быть платежи одним и тем же клиентом в предыдущие месяцы.
Это таблица с несколькими строками для каждого платежа, поэтому мне нужно использовать group by.
Я пытаюсь найти наилучший способ запроса информации.
Я полагаю, что он должен быть построен динамически (я прав? Можно ли это сделать без динамического SQL?), И видел различные подходы при поиске в Интернете:
динамически добавлять строки в предложении select, используя регистры, например, такой запрос: SQL-запрос для сравнения продаж продукта по месяцам
динамически добавлять UNIONS в одну и ту же таблицу для каждого сравниваемого месяца
динамически добавлять ЛЕВЫЕ СОЕДИНЕНИЯ в одну и ту же таблицу для каждого сравниваемого месяца
Код концепции для подхода 1:
DECLARE @month int, @monthNum int
SET @month = 103
SET @monthNum = 1
SELECT
name,ID,Property
,MAX(CASE WHEN month = @month THEN month ELSE 0 END) AS month
,SUM(CASE WHEN month = @month THEN paymentSum ELSE 0 END) AS paymentSum
,MAX(CASE WHEN month = @month THEN PaymentFailReason ELSE 0 END) AS PaymentFailReason
,MAX(CASE WHEN month = @month -1 THEN month ELSE 0 END) AS monthMinusOne
,SUM(CASE WHEN month = @month -1 THEN paymentSum ELSE 0 END) AS paymentSumMinusOne
,MAX(CASE WHEN month = @month -1 THEN PaymentFailReason ELSE 0 END) AS PaymentFailReasonMinusOne
FROM
payments
WHERE
month BETWEEN @month -@monthNum AND @month AND status = 2
GROUP BY
name,ID,Property
Статус = 2 означает, что платеж был неудачным.
Есть ли предпочтительное решение в таком случае?
Один подход более эффективен, чем другой?
Пример данных:
month ID name Property paymentSum PaymentFailReason Status
100 1 Aron A 100 Has No money 2
100 2 Burt B 100 Has No money 2
100 3 Carl C 50 Has No money 2
101 1 Aron A 50 Has No money 2
101 2 Burt B 50 Has No money 2
101 3 Carl C 50 Has No money 2
102 1 Aron A 100 Has No money 2
102 2 Burt B 100 1
102 3 Carl C 100 Has No money 2
103 1 Aron A 102 Has No money 2
103 2 Burt B 102 Has No money 2
103 3 Carl C 102 1
Результаты запроса вышеуказанных данных за месяц № 103 и 1 месяц назад должны быть:
month ID name Property paymentSum PaymentFailReason Status monthMinusOne paymentSumMinusOne PaymentFailReasonMinusOne
103 1 Aron A 102 Has No money 2 102 100 Has No money
103 2 Burt B 102 Has No money 0 102 0 0
Карл заплатил успешно на 103, поэтому он не в результатах.
Берт успешно заплатил 102, поэтому его данные за этот месяц неактуальны (все нули).
Edit:
Я создал динамический SQL-запрос, который зацикливается на создание случаев на количество месяцев назад, определенных пользователями. занимает много времени ... Чего мне не хватает? ЛЕВЫЕ СОЕДИНЕНИЯ И СОЮЗЫ были бы лучше?