loading..
Русский    English
16:35
листать

Первый день недели стр. 2

Функция @@DATEFIRST

@@DATEFIRST возвращает число, которое определяет первый день недели, установленный для текущей сессии. При этом 1 соответствует понедельнику, а 7, соответственно, воскресенью. Т.е. если

Консоль
Выполнить
  1. SELECT @@DATEFIRST;
возвращает 7, то первым днем недели считается воскресенье (соответствует текущим настройкам на сайте).

Для того, чтобы решение нашей задачи не зависело от значения, установленного для первого дня недели, воспользуемся функцией @@DATEFIRST. Сделать это можно, например, так

Консоль
Выполнить
  1. WITH num(n) AS(
  2. SELECT 0
  3. UNION ALL
  4. SELECT n+1 FROM num
  5. WHERE n < 6),
  6. dat AS (
  7. SELECT DATEADD(dd,  n,  CAST('2013-01-01' AS DATETIME)) AS day FROM num
  8. )
  9. SELECT day, DATENAME(dw, day) week_day FROM dat  WHERE DATEPART(dw, day) =
  10. 1+(8-@@DATEFIRST) % 7;

day   week_day
2013-01-07    Monday

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

  1. SET DATEFIRST 1;
  2. SELECT @@DATEFIRST;
то мы получим значение 1, т.е. неделя теперь начинается с понедельника.

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

  1. SET LANGUAGE us_english;
  2. SELECT @@DATEFIRST;
то опять получим 7 (воскресенье), поскольку это значение DATEFIRST принято по умолчанию для английского (американского) языка. В то время как выбор русского языка (SET LANGUAGE russian;) сделает первым днем недели понедельник.

Однако вы можете поменять параметры языка и первого дня недели одновременно, чтобы, скажем, получить английский язык, и при этом педеля будет начинаться с понедельника:

  1. SET DATEFIRST 1;
  2. SET LANGUAGE us_english;
  3. SELECT @@DATEFIRST;

Языковые настройки влияют, в частности, на символьное представление компонентов даты/времени. Сравните, например, результаты:

  1. DECLARE @dt DATE = '2012-12-17'; -- 17 декабря 2012 года
  2. SET LANGUAGE us_english;
  3. SELECT DATENAME(DW, @dt) AS day_of_week, DATENAME(MONTH,@dt) AS month;

day_of_week   month
Monday    December

  1. SET LANGUAGE russian;
  2. SELECT DATENAME(DW, @dt) AS day_of_week, DATENAME(MONTH, @dt) AS month;

day_of_week   month
понедельник    Декабрь

  1. SET LANGUAGE german;
  2. SELECT DATENAME(DW, @dt) AS day_of_week, DATENAME(MONTH, @dt) AS month;

day_of_week   month
Montag    Dezember

Вывод. Если вы хотите, чтобы зависящие от настроек сервера/базы запросы всегда давали верный результат, можно задавать необходимые настроечные параметры для сессии, в которой эти запросы выполняются, или же проверять в каждом подобном запросе значения соответствующих параметров, в частности, с помощью функции @@DATEFIRST.

Особенности: MSSQL

Решить эту задачу (Определить дату, на которую выпал первый понедельник января 2013 года.) можно и без применения функции @@DATEFIRST, воспользовавшись методом, предложенным Ициком Бен-Ганом [8]. Идея решения заключается в том, что:

1. Первое января 1900г. было понедельником.

2. Количество дней между двумя одинаковыми днями недели всегда кратно семи.

  1. declare  @anchor_date datetime
  2. declare  @reference_date datetime
  3. SELECT @anchor_date='19000101', @reference_date='20130505'
  4. SELECT DATEADD(day, DATEDIFF(day, @anchor_date,
  5. DATEADD(year, DATEDIFF(year, '19000101', @reference_date), '19000101') - 1) /7*7 + 7,
  6. @anchor_date);
Автор: Гершович В.И.

Особенности: MSSQL
Можно упомянуть еще один способ решения этой задачи без @@DATEFIRST, который использует сравнение любой из функций DATEPART/DATENAME с такой же функцией от даты, которая ЗАВЕДОМО является понедельником. Например, от уже упомянутого 1-го января 1900г.

Тогда первоначальный запрос из этой главы выглядел бы так:

  1. SELECT day FROM dat  WHERE DATEPART(dw, day) = DATEPART(dw, '19000101');
или так
  1. SELECT day FROM dat  WHERE DATENAME(dw, day) = DATENAME(dw, '19000101');
Автор: Курочкин П.А.

Рекомендуемые упражнения: 78, 99, 110, 118

Bookmark and Share
Страницы: 1 2
Тэги:
ALL AND AUTO_INCREMENT AVG battles CASE CAST CHAR CHARINDEX CHECK classes COALESCE CONSTRAINT Convert COUNT CROSS APPLY CTE DATEADD DATEDIFF DATENAME DATEPART DATETIME DDL DEFAULT DELETE DISTINCT DML EXCEPT EXISTS EXTRACT FOREIGN KEY FROM FULL JOIN GROUP BY Guadalcanal HAVING IDENTITY IN INFORMATION_SCHEMA INNER JOIN insert INTERSECT IS NOT NULL IS NULL ISNULL laptop LEFT LEFT OUTER JOIN LEN maker Больше тэгов
Учебник обновлялся
месяц назад
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.