Как написать переменную в SQL, используя Dateadd и DateDiff для поиска последних двух дней предыдущего месяца - PullRequest
1 голос
/ 04 апреля 2019

Я пытаюсь написать переменную, используя dateadd и datediff, которые показывают последние два дня предыдущего месяца. Одна переменная будет со второго по последний день предыдущего месяца, с которой у меня проблемы. Другой будет последний день предыдущего месяца, который я смог получить. Я использую SQL Server.

Я пытался найти его в стеке и видел только последний день предыдущего месяца, а НЕ второй и последний день. Я попытался выучить dateadd и datediff (что я все еще хочу сделать).

Это то, что я пробовал до сих пор:

Declare @CurrentMonth as date = '3/1/2019'
Declare @SecLastDayPrevMonth as date = DATEADD(MONTH, DATEDIFF(MONTH, 0, @currentmonth), -2) 
Declare @LastDayPrevMonth as date = DATEADD(MONTH, DATEDIFF(MONTH, 0, @currentmonth), -1) 

Результаты, которые я получаю для seclastdayPrevMonth: 28.02.2009. Вместо этого я хотел бы 2/27/2019

Я также получаю 28.02.2009 за lastdayprevmonth, чего я и хочу.

Я пишу переменные, потому что текущий месяц будет меняться каждый месяц, и вместо необходимости обновлять другие дни, которые мне нужны в моем запросе, я хочу использовать переменные, поэтому я обновляю только текущий месяц, а все остальное проходит через ,

И объяснение того, почему мой dateadd / datediff неверен, и объяснение того, почему правильный dateadd / datediff такой, какой он есть, будет очень полезно

Ответы [ 2 ]

3 голосов
/ 04 апреля 2019

Почему бы не обратиться к последнему дню при расчете второго последнего дня? Кроме того, использование DATEADD очень странно. Синтаксис DATEADD(interval, increment, datetime)

Declare @recmonth as date = '3/1/2019'
Declare @LastDayPrevMonth as date = EOMONTH(DATEADD(MONTH, -1, @RecMonth))
Declare @SecLastDayPrevMonth as date = DATEADD(DAY, -1, @LastDayPrevMonth)


SELECT @SecLastDayPrevMonth, @LastDayPrevMonth

Таким образом, мы можем вычислить последний день предыдущего месяца, вычитая один месяц из даты, а затем вызывая EOMONTH, который возвращает последний день данного месяца. Тогда второй последний день просто вычитает один день из этого.

Урожайность:

SecLastDayPrevMonth LastDayPrevMonth
------------------- ----------------
2019-02-27          2019-02-28
0 голосов
/ 04 апреля 2019

Что касается «почему», DATEDIFF() принимает 3 аргумента: datepart (строковое представление определенной части даты), startdate, enddate (оба из которых должны быть преобразованы в объект даты-выхода).

0 - это, по сути, эпоха SQL, которая в данном случае 1/1/1900.Таким образом, разница в месяцах между 0 и 3/1/2019 составляет (119 * 12) +2 (+2, потому что мы исключаем март, поскольку мы не рассчитываем полный месяц) = 1430 месяцев.

Затем мы пытаемся добавить 2 месяца к нашей стоимости.DATEADD() принимает 3 аргумента: datepart, number, date.Но, в этом примере, вы добавляете 1430 месяцев к любой дате, до которой конвертируется -2 (в этом случае, я думаю, это будет 30.12.1899 или за 2 дня до эпохи).Таким образом, 1430 месяцев после 30.12.1999 будут 30.02.2009, но в феврале в Феврале будет только 28 дней, поэтому он возвращается 28.02.2009.В високосный год он, вероятно, вернется 2/29/2019.

Чтобы получить @LastDayPrevMonth и @SecLastDayPrevMonth только с DATEDIFF() и DATEADD(), вам просто нужно немного изменить свои вычисления,

Первое, что вы хотите сделать, это найти первый день вашего данного месяца.Это можно сделать с помощью DATEADD(month,DATEDIFF(month,0,@CurrentDate),0).По сути, мы используем то же самое, что использовали выше, чтобы вычислить количество месяцев с начала эпохи, но затем мы добавляем эти месяцы назад к эпохе.

Теперь, когда мы знаем первый день данного месяца, все, что нам нужно сделать, это вычесть дни, чтобы получить день из предыдущего месяца.

Итак,

DECLARE @CurrentDate date = '2019-03-15' ; -- Changed it to something in the middle of the month.

DECLARE @FirstDayOfGivenMonth = DATEADD(month,DATEDIFF(month,0,@CurrentDate),0) ; -- 3/1/2019

DECLARE @LastDayOfPrevMonth date = DATEADD(day,-1,@FirstDayOfThisMonth) ; -- 2/28/2019
DECLARE @SecLastDayOfPrevMonth date = DATEADD(day, -2, @FirstDayOfThisMonth) ; -- 2/27/2019

SELECT @LastDayOfPrevMonth AS LDPM, @SecLastDayOfPrevMonth AS SLDPM ;

DECLARE @FourDaysLeftInPrevMonth date = DATEADD(day, -4, @FirstDayOfThisMonth) ; -- 2/25/2019
SELECT @FourDaysLeftInPrevMonth AS FourDaysLeftPrev ;

Конечно, начиная с SQL 2012, все это можно сделать гораздо проще с помощью функции EOM(), чтобы добраться до последнего дня месяца.Но если бы вы могли использовать только две оригинальные функции из исходного вопроса, это был бы один из способов получить нужные значения.

...