SQL. Подсчёт кол-ва лет. DATE_FORMAT не является известным имя встроенной функции

Пытаюсь правильно посчитать кол-во лет

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[tableNum3](
    [Код] [int] IDENTITY(1,1) NOT NULL,
    [birthday] [datetime] NULL,
    [age] [int] null,
 CONSTRAINT [PK_tableNum3] PRIMARY KEY CLUSTERED 
(

    [Код] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SELECT birthday,
  (
    (YEAR(GETDATE) - YEAR(birthday)) - (DATE_FORMAT(GETDATE, '%m%d') < DATE_FORMAT(birthday, '%m%d'))
  ) AS age
FROM tableNum3 

Выдаёт такую ошибку: Сообщение 195, уровень 15, состояние 10, строка 27 DATE_FORMAT не является известным имя встроенной функции.

Как быть, что делать?


Ответы (3 шт):

Автор решения: Aziz Umarov

Используйте DATEDIFF ( datepart , startdate , enddate )

SELECT DATEDIFF( year , birthday, GETDATE())
→ Ссылка
Автор решения: Герман Борисов
  1. В MS SQL нет прямого аналога DATE_FORMAT.
  2. Еще и нет неявного преобразования Boolean в число. Выражение вида A - (C < D) вернет ошибку несовместимости типов. Нужно использовать CASE
  3. Также вместо YEAR(GETDATE()) лучше использовать стандартную функцию DATEPART. А данном случае еще лучше DATEDIFF.

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

Академически верное сравнение: M1 < M2 || M1 = M2 && D1 < D2

Итого получаем:

DATEDIFF(YEAR, birthday, GETDATE()) - CASE WHEN DATEPART(MONTH, GETDATE()) < DATEPART(MONTH, birthday) OR DATEPART(MONTH, GETDATE()) = DATEPART(MONTH, birthday) AND DATEPART(DAY, GETDATE()) < DATEPART(DAY, birthday) THEN 1 ELSE 0 END

Для упрощения можно учесть тот факт, что для записи в формате MMDD лексикографической сравнение (как строки) соответствует сравнению дат.

Не совсем красиво можно заменить DATE_FORMAT с форматом '%m%d' на вызов CONVERT с отрезанием года: RIGHT(CONVERT(VARCHAR(8), GETDATE(), 112), 4)

Тогда получим:

DATEDIFF(YEAR, birthday, GETDATE()) - CASE WHEN RIGHT(CONVERT(VARCHAR(8), GETDATE(), 112), 4) < RIGHT(CONVERT(VARCHAR(8), birthday, 112), 4) THEN 1 ELSE 0 END
→ Ссылка
Автор решения: Тушканчик

Спасибо что помогли, но всё оказалось куда проще. При создании таблицы.

    [birthday] [datetime] NULL,
    [age]  AS (floor(CONVERT([int],getdate()-[birthday])/(365.25))),

всё отлично работает

→ Ссылка