YEAR: примеры (SQL)
YEAR(date): intОписание функции YEAR
Функция YEAR в MS SQL Server предназначена для извлечения числового значения года из указанного выражения даты и времени. Эта функция является одной из наиболее часто используемых при работе с датами для анализа, группировки или фильтрации данных по календарным годам.
Синтаксис функции прост: YEAR ( date ).
В качестве аргумента date принимается выражение, которое можно неявно преобразовать к одному из следующих типов данных: date, datetime, datetime2, datetimeoffset или smalldatetime. Функция также может работать с строковыми литералами в формате даты.
Возвращаемым значением является целое число (int), представляющее год указанной даты. Диапазон возвращаемых значений зависит от типа данных аргумента. Для распространенного типа datetime возвращаются значения от 1753 до 9999. Если аргумент имеет значение NULL, функция также возвращает NULL.
Короткие примеры использования
Пример 1: Извлечение года из явной даты.
SELECT YEAR('2023-11-15T08:30:00') AS ResultYear;ResultYear ----------- 2023
Пример 2: Использование с полем таблицы.
DECLARE @Sales TABLE (OrderDate datetime);
INSERT INTO @Sales VALUES ('2021-05-20'), ('2022-12-01');
SELECT OrderDate, YEAR(OrderDate) AS OrderYear FROM @Sales;OrderDate OrderYear ----------------------- ---------- 2021-05-20 00:00:00.000 2021 2022-12-01 00:00:00.000 2022
Пример 3: Работа со строковым литералом.
SELECT YEAR('01/15/2020') AS ResultYear;ResultYear ----------- 2020
Пример 4: Обработка NULL-значения.
SELECT YEAR(NULL) AS ResultYear;ResultYear ----------- NULL
Похожие функции в MS SQL
В MS SQL Server для работы с компонентами даты существуют другие функции.
DATEPART(year, date) - Аналогична функции YEAR и возвращает тот же результат. Применяется, когда нужен единообразный синтаксис для извлечения различных частей даты (месяца, дня, недели).
DATENAME(year, date) - Возвращает год в виде символьной строки (nvarchar). Различие с YEAR становится заметным только в контексте преобразований типов.
FORMAT(date, 'yyyy') - Возвращает год в виде отформатированной строки. Эта функция значительно менее производительна, чем YEAR, но полезна, когда требуется сложное форматирование в рамках одной операции.
Функцию YEAR предпочтительнее использовать для простого и быстрого извлечения числового значения года, особенно в условиях обработки больших объемов данных. DATEPART стоит выбирать для унификации кода. FORMAT применяется только в случаях необходимости специфического строкового представления.
Аналоги функции в других СУБД
MySQL: Функция YEAR(date) идентична по синтаксису и поведению MS SQL.
SELECT YEAR('2023-07-04');2023
Oracle: Для извлечения года используется функция EXTRACT(YEAR FROM date). Она более универсальна и может извлекать другие компоненты.
SELECT EXTRACT(YEAR FROM DATE '2023-07-04') FROM dual;2023
PostgreSQL: Также поддерживает стандартный SQL оператор EXTRACT(YEAR FROM date) и дополнительно функцию DATE_PART('year', date).
SELECT EXTRACT(YEAR FROM TIMESTAMP '2023-07-04 10:30:00');2023
SQLite: Не имеет встроенной функции YEAR. Год извлекается с помощью функции strftime('%Y', date_string), которая возвращает строку.
SELECT strftime('%Y', '2023-07-04');2023
Sybase ASE: Использует функцию YEAR(date), аналогичную MS SQL.
Типичные ошибки
1. Передача аргумента несовместимого типа данных, который не может быть неявно преобразован в дату.
SELECT YEAR('Not a date') AS ResultYear;Msg 241, Level 16, State 1... Conversion failed when converting date and/or time from character string.
2. Ожидание, что функция вернет данные в определенном формате (например, с ведущими нулями). YEAR всегда возвращает целое число.
SELECT YEAR('2023-01-01') AS YearNum;
-- Возвращает 2023, а не '2023' или '23'.3. Использование с типами данных, у которых есть только компонент времени (time). Это приводит к ошибке.
SELECT YEAR(CAST('14:30:00' AS time));Msg 9810, Level 16, State 11... The datepart year is not supported by date function year for data type time.
4. Неучет того, что для типа datetime минимальный год - 1753. Попытка использовать более раннюю дату вызовет ошибку.
SELECT YEAR('1492-01-01');Msg 242, Level 16, State 3... The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Изменения в последних версиях
Функция YEAR не претерпела значительных синтаксических изменений или изменений в поведении в последних версиях MS SQL Server (2012, 2014, 2016, 2017, 2019, 2022).
Основные связанные улучшения касаются поддержки новых типов данных даты-времени, введенных в SQL Server 2008: date, datetime2, datetimeoffset. Функция YEAR корректно работает с этими типами, расширяя диапазон обрабатываемых дат. Например, для типа date и datetime2 можно извлечь год из дат, начиная с 0001-01-01.
Расширенные примеры использования
Пример 1: Группировка продаж по году для построения отчетов.
SELECT YEAR(OrderDate) AS SaleYear, COUNT(*) AS OrdersCount, SUM(TotalAmount) AS TotalRevenue
FROM Sales.Orders
GROUP BY YEAR(OrderDate)
ORDER BY SaleYear;Пример 2: Фильтрация записей за последние 5 полных календарных лет.
DECLARE @CurrentYear int = YEAR(GETDATE());
SELECT *
FROM Events
WHERE YEAR(EventDate) BETWEEN @CurrentYear - 5 AND @CurrentYear - 1;Пример 3: Вычисление возраста на основе года рождения.
SELECT FullName, BirthDate, YEAR(GETDATE()) - YEAR(BirthDate) AS ApproximateAge
FROM Persons;
-- Внимание: Этот расчет точен только если день и месяц рождения уже прошли в текущем году.Пример 4: Динамическое формирование имени физического файла базы данных с указанием года.
DECLARE @BaseName varchar(100) = 'Backup_';
DECLARE @CurrentYear varchar(4) = CAST(YEAR(GETDATE()) AS varchar(4));
DECLARE @FileName varchar(150) = @BaseName + @CurrentYear + '.bak';
SELECT @FileName AS BackupFile;
-- Результат: 'Backup_2023.bak' (в зависимости от текущего года)Пример 5: Использование в выражении CASE для категоризации по десятилетиям.
SELECT ProductName, ReleaseDate,
CASE
WHEN YEAR(ReleaseDate) BETWEEN 2020 AND 2029 THEN '2020s'
WHEN YEAR(ReleaseDate) BETWEEN 2010 AND 2019 THEN '2010s'
ELSE 'Earlier'
END AS Decade
FROM Products;Пример 6: Комбинация с другими функциями даты для извлечения первого дня года.
SELECT DATEFROMPARTS(YEAR(GETDATE()), 1, 1) AS FirstDayOfCurrentYear;Пример 7: Поиск записей, где год в дате не соответствует ожидаемому диапазону (например, для очистки данных).
SELECT * FROM LogEntries
WHERE YEAR(CreatedDate) NOT BETWEEN 2000 AND YEAR(GETDATE());