Как добавить 1 месяц к 30 или 31 января, а после февраля это должно занять 30 или 31 марта соответственно - PullRequest
0 голосов
/ 27 мая 2020

Я столкнулся с этой проблемой и сегодня провожу много времени. Итак, я подумал поделиться им здесь:

У меня есть таблица, в которой мы храним debitDate , и у нас есть хранимая процедура, где каждый месяц мы устанавливаем дату дебетования на следующий месяц в таблице.

Итак, если его дата дебетования 29th Jan, 2020 -> 29th Feb, 2020 -> 29th March, 2020 - значит, должно быть go вот так. Я использую функцию DATEADD () в хранимой процедуре.

Но на 30-м и 31-м я столкнулся с проблемой. В ближайшие годы он должен работать, как показано ниже:

Желаемое поведение :

30th Jan, 2020 -> 29th Feb, 2020 -> 30th Mar, 2020 -> 30th Apr, 2020

30th Jan, 2021 -> 28th Feb, 2021 -> 30th Mar, 2021 -> 30th Apr, 2021

31st Jan, 2020 -> 29th Feb, 2020 -> 31st Mar, 2020 -> 30th Apr, 2020

Проблема :

30th Jan, 2020 -> 29th Feb, 2020 -> 29th Mar, 2020 -> 29th Apr, 2020

30th Jan, 2021 -> 28th Feb, 2021 -> 28th Mar, 2021 -> 28th Apr, 2021

31st Jan, 2020 -> 29th Feb, 2020 -> 29th Mar, 2020 -> 29th Apr, 2020

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Решение 1 :

Для решения я подумал, что могу добавить новый столбец в таблицу как previousDebitDate , и когда мы обновим дату дебета, мы проверим , если предыдущий деньDebitDate равен 30 или 31. Если true, то

DATEADD(MONTH, 2, @previousDebitDate)

else

DATEADD(MONTH, 1, @debitDate)

Если у кого-то есть лучшее решение, пожалуйста, опубликуйте свой ответ.

Решение 2 :

Для этой проблемы лучшим решением является добавление debitDay в качестве нового столбца в таблицу и сохранение только дневной части (например: 30) и вычисляйте дату дебета каждый месяц на лету.

Я думаю, что решение 2 лучше! Спасибо @Arvo !!!

0 голосов
/ 27 мая 2020
• 1000 1007 *
WITH CTE AS
(
  SELECT 1 N, Dates, Dates ExpectedValue
  FROM Data
  UNION ALL
  SELECT N+1, DATEADD(Month, 1, Dates), DATEFROMPARTS(YEAR(ExpectedValue), MONTH(DATEADD(Month, 1, ExpectedValue)), 
               CASE WHEN DAY(EOMONTH(DATEADD(Month, 1, ExpectedValue))) > 30 THEN 30
                    ELSE DAY(EOMONTH(DATEADD(Month, 1, ExpectedValue)))
               END)
  FROM CTE
  WHERE N < 15
)
SELECT *
FROM CTE
ORDER BY N;

Возвращает:

+----+------------+---------------+
| N  |   Dates    | ExpectedValue |
+----+------------+---------------+
|  1 | 2020-01-30 | 2020-01-30    |
|  2 | 2020-02-29 | 2020-02-29    |
|  3 | 2020-03-29 | 2020-03-30    |
|  4 | 2020-04-29 | 2020-04-30    |
|  5 | 2020-05-29 | 2020-05-30    |
|  6 | 2020-06-29 | 2020-06-30    |
|  7 | 2020-07-29 | 2020-07-30    |
|  8 | 2020-08-29 | 2020-08-30    |
|  9 | 2020-09-29 | 2020-09-30    |
| 10 | 2020-10-29 | 2020-10-30    |
| 11 | 2020-11-29 | 2020-11-30    |
| 12 | 2020-12-29 | 2020-12-30    |
| 13 | 2021-01-29 | 2020-01-30    |
| 14 | 2021-02-28 | 2020-02-29    |
| 15 | 2021-03-28 | 2020-03-30    |
+----+------------+---------------+

Вот db <> fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...