SQL Datepart добавление года

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

У меня есть список дат, начиная с 1960 по 2016 год. Я хочу взять месяц и день даты и:

    - If Month and Day > Today then add 2016 as Yr BUT
   - If Month and Day < Today then add 2017 as Yr
  

Вот SQL, который у меня есть до сих пор:

 Select DATEPART(MM, Date) as Month,
  DATEPART(dd, Date) as DayNum
  From DateTable
  WHERE CategoryID = 3
  

Комментарии:

1. можете ли вы показать, как будет выглядеть ваш образец вывода?

Ответ №1:

Что-то вроде этого:

 select (case when month(date) * 100   day(date) < month(getdate()) * 100   day(getdate())
             then datefromparts(2017, month(date), day(date)
             else datefromparts(2016, month(date), day(date)
        end) as next_anniversary
from datetable
where categoryid = 3;
  

На самом деле вам не нужно выполнять арифметику. Это эквивалентно:

 select (case when month(date) < month(getdate()) or
                  month(date) = month(getdate()) and day(date) < day(getdate())
             then datefromparts(2017, month(date), day(date)
             else datefromparts(2016, month(date), day(date)
        end) as next_anniversary
from datetable
where categoryid = 3;
  

Также datefromparts() доступно в SQL Server 2012 . Вы можете объединить аналогичные функции в более ранних версиях SQL Server, но это проще.

Ответ №2:

Используйте приведенный ниже запрос для версии SQL Server от 2008.

      SELECT CASE WHEN month(date) < =month(getdate())  and day(date) < day(getdate()) 
                   THEN CONVERT(DATE,'2017-' 
                              CAST(Month(date) AS VARCHAR(2)) '-' CAST(Day(date) AS VARCHAR(2)))
                    ELSE CONVERT(DATE,'2016-' 
                             CAST(Month(date) AS VARCHAR(2)) '-' CAST(Day(date) AS VARCHAR(2))) END as new_date
     FROM datetable
     WHERE categoryid = 3;
  

Ответ №3:

Это простой способ сделать это. Работает просто отлично

 SELECT CASE WHEN SUBSTRING(CAST(CAST(Date AS DATE) AS NVARCHAR),6,10)<SUBSTRING(CAST(CAST(GETDATE() AS DATE) AS NVARCHAR),6,10)
THEN datefromparts(2017, month(Date), day(Date))
ELSE datefromparts(2016, month(Date), day(Date)) END
FROM datetable
WHERE categoryid = 3;
  

Дайте мне знать, если это работает и для вас.

Если вы используете SQL Server 2008, DATEFROMPARTS не будет работать, вместо этого используйте

 SELECT CASE WHEN SUBSTRING(CAST(CAST(Date AS DATE) AS NVARCHAR),6,10)<SUBSTRING(CAST(CAST(GETDATE() AS DATE) AS NVARCHAR),6,10)
THEN DATEADD(YEAR, 2017-YEAR(ex_date), Date)
ELSE DATEADD(YEAR, 2016-YEAR(ex_date), Date)
END
FROM datetable
WHERE categoryid = 3;