DATEPART: примеры (SQL)

Работа с DATEPART в SQL Server: извлечение компонентов даты
Раздел: Даты и времени функции, Дата и время
DATEPART(datepart, date): int

Описание функции DATEPART

Функция DATEPART в MS SQL Server возвращает целое число, представляющее указанную часть даты (год, квартал, месяц, день и т.д.). Она применяется для анализа и извлечения отдельных компонентов из значений типа datetime, date, time, datetime2 или datetimeoffset.

Синтаксис функции: DATEPART(datepart, date).

Аргумент datepart определяет часть даты для возврата. Допустимые значения:

  • year (yy, yyyy) – год.
  • quarter (qq, q) – квартал (1-4).
  • month (mm, m) – месяц (1-12).
  • dayofyear (dy, y) – день года (1-366).
  • day (dd, d) – день месяца (1-31).
  • week (wk, ww) – неделя года (1-53).
  • weekday (dw, w) – день недели (1-7, где 1=воскресенье).
  • hour (hh) – час (0-23).
  • minute (mi, n) – минута (0-59).
  • second (ss, s) – секунда (0-59).
  • millisecond (ms) – миллисекунда (0-999).
  • microsecond (mcs) – микросекунда (0-999999).
  • nanosecond (ns) – наносекунда (0-999999999).
  • TZoffset (tz) – смещение часового пояса в минутах (для datetimeoffset).
  • ISO_WEEK (isowk, isoww) – номер недели по стандарту ISO 8601 (1-53).

Аргумент date – выражение, которое можно привести к типу date, time, datetime, datetime2 или datetimeoffset.

Функция возвращает целое число, соответствующее указанной части даты. Для недопустимых дат возвращается ошибка.

Примеры использования

Извлечение различных частей даты:

SELECT DATEPART(year, '2023-12-31') AS YearPart;
YearPart
2023
SELECT DATEPART(quarter, '2023-08-15') AS QuarterPart;
QuarterPart
3

Работа с временем:

SELECT DATEPART(hour, '14:30:25') AS HourPart;
HourPart
14

Использование сокращенных обозначений:

SELECT DATEPART(mm, '2023-05-10') AS MonthPart;
MonthPart
5

Дата со временем:

SELECT DATEPART(minute, '2023-07-20 09:45:30') AS MinutePart;
MinutePart
45

День недели:

SELECT DATEPART(weekday, '2023-11-14') AS WeekdayPart;
WeekdayPart
3

ISO неделя:

SELECT DATEPART(ISO_WEEK, '2023-01-01') AS ISOWeekPart;
ISOWeekPart
52

Похожие функции в MS SQL

В MS SQL Server существуют другие функции для работы с датами:

  • YEAR(date) – возвращает год даты. Аналогично DATEPART(year, date).
  • MONTH(date) – возвращает месяц даты. Аналогично DATEPART(month, date).
  • DAY(date) – возвращает день месяца. Аналогично DATEPART(day, date).
  • DATENAME(datepart, date) – возвращает строковое представление части даты (например, название месяца).
  • DATEFROMPARTS – создает дату из отдельных числовых компонентов.

Функции YEAR, MONTH, DAY предпочтительнее использовать для простого извлечения года, месяца или дня, так как они короче. DATENAME удобна для получения текстовых значений. DATEPART более универсальна и позволяет извлекать разнообразные части даты, включая кварталы, недели и время.

Аналоги в других СУБД

В других базах данных существуют похожие функции:

MySQL: Функции EXTRACT(unit FROM date), YEAR(), MONTH(), DAY(), HOUR() и т.д.

SELECT EXTRACT(YEAR FROM '2023-12-31');
2023

PostgreSQL: Также используется EXTRACT(unit FROM date) или date_part('unit', date).

SELECT date_part('month', TIMESTAMP '2023-08-15');
8

Oracle: Функция EXTRACT(unit FROM date) или TO_CHAR с маской.

SELECT EXTRACT(DAY FROM DATE '2023-11-14') FROM dual;
14

SQLite: Используется функция strftime('%unit', date).

SELECT strftime('%Y', '2023-05-10');
2023

Отличия: в MS SQL аргумент datepart передается как ключевое слово, а в других СУБД часто используется строка. Функция DATEPART возвращает целое число, тогда как в некоторых СУБД аналоги могут возвращать строки.

Типичные ошибки

1. Передача недопустимого значения datepart.

SELECT DATEPART(decade, '2023-01-01');
Сообщение об ошибке: Недопустимое значение параметра datepart для функции datepart.

2. Передача значения NULL, что приводит к возврату NULL.

SELECT DATEPART(year, NULL) AS Result;
Result
NULL

3. Неявное преобразование строки в дату может вызвать ошибку при неверном формате.

SELECT DATEPART(month, '31-12-2023');
Может вызвать ошибку преобразования в зависимости от настроек языка.

4. Попытка извлечь компонент, не существующий в типе данных (например, час из типа date).

SELECT DATEPART(hour, CAST('2023-07-20' AS date));
Результат: 0 (так как тип date не содержит времени, час считается равным 0).

Изменения в последних версиях

В SQL Server 2008 были добавлены поддержка типов данных date, time, datetime2 и datetimeoffset, а также аргументы microsecond, nanosecond и TZoffset.

В SQL Server 2012 появилась поддержка аргумента ISO_WEEK для DATEPART.

Современные версии SQL Server (2016 и выше) не вносили значительных изменений в работу функции DATEPART, но улучшили производительность и совместимость с другими функциями даты и времени.

Расширенные примеры

Анализ интервалов между датами:

Пример sql
SELECT 
    DATEDIFF(day, '2023-01-01', '2023-12-31') AS DaysDiff,
    DATEPART(quarter, '2023-08-15') AS QuarterOfDate;
DaysDiff    QuarterOfDate
364         3

Группировка по частям даты:

Пример sql
SELECT 
    DATEPART(year, OrderDate) AS OrderYear,
    DATEPART(month, OrderDate) AS OrderMonth,
    COUNT(*) AS OrdersCount
FROM Orders
GROUP BY DATEPART(year, OrderDate), DATEPART(month, OrderDate)
ORDER BY OrderYear, OrderMonth;
OrderYear   OrderMonth  OrdersCount
2022        1           150
2022        2           165

Определение начала недели (понедельник):

Пример sql
DECLARE @Date date = '2023-11-16';
SELECT DATEADD(day, 2 - DATEPART(weekday, @Date), @Date) AS WeekStartMonday;
WeekStartMonday
2023-11-13

Извлечение наносекунд (требует тип datetime2):

Пример sql
SELECT DATEPART(nanosecond, '2023-04-05 12:34:56.123456789') AS NanosecondPart;
NanosecondPart
123456789

Смещение часового пояса для datetimeoffset:

Пример sql
SELECT DATEPART(TZoffset, '2023-10-10 10:00:00 +03:00') AS TimezoneOffset;
TimezoneOffset
180

Подсчет рабочих дней (исключая выходные):

Пример sql
DECLARE @StartDate date = '2023-11-01', @EndDate date = '2023-11-30';
SELECT 
    COUNT(*) AS WorkingDays
FROM (SELECT TOP (DATEDIFF(day, @StartDate, @EndDate) + 1)
          DATEADD(day, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1, @StartDate) AS d
      ) dates
WHERE DATEPART(weekday, d) NOT IN (1, 7);
WorkingDays
22

MS SQL DATEPART function comments

En
DATEPART Returns an integer representing the specified datepart of the specified date