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 шт):
Используйте DATEDIFF ( datepart , startdate , enddate )
SELECT DATEDIFF( year , birthday, GETDATE())
- В MS SQL нет прямого аналога DATE_FORMAT.
- Еще и нет неявного преобразования Boolean в число. Выражение вида
A - (C < D)вернет ошибку несовместимости типов. Нужно использоватьCASE - Также вместо
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))),
всё отлично работает