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

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

Задача. Определить дату, на которую выпал первый понедельник января 2013 года.

При некоторых предположениях решить эту задачу можно следующим образом:

Консоль
Выполнить
  1. WITH num(n) AS(/* с помощью рекурсивного CTE создаем таблицу со столбцом n
  2.                      и значениями от 0 до 6 */
  3. SELECT 0
  4. UNION ALL
  5. SELECT n+1 FROM num
  6. WHERE n < 6),
  7. dat AS (/* создаем таблицу с датами от 1 до 7 января 2013 года */
  8. SELECT DATEADD(dd,  n,  CAST('2013-01-01' AS DATETIME)) AS day FROM num
  9. )
  10. SELECT day FROM dat  WHERE DATEPART(dw, day) = 1; /* выбираем день, соответствующий
  11.                         первому дню недели */

Предположение, о котором говорилось выше, состоит в том, что первым днем недели считается понедельник. Однако если вы выполните этот запрос на сайте sql-ex.ru, то получите

day
2013-01-06
А это - воскресенье. Причина в том, что настройки на сайте полагают первым днем недели воскресенье. А можно ли написать решение, которое не зависело бы от настроек сервера? Попробуем сделать так: будем не номер дня использовать при фильтрации, а его название (поменяется лишь последняя строка, но я повторяю весь запрос с тем, чтобы его можно было выполнить без редактирования):

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

day
2013-01-07

Теперь правильно, но будет ли этот запрос всегда верен, если "зашить" его в код приложения? Ответ - нет. Если я поменяю языковые настройки:

  1. SET LANGUAGE russian;
то получу пустой набор строк, поскольку в этом случае последнюю строку запроса следовало бы написать так

  1. SELECT day FROM dat  WHERE DATENAME(dw, day) = N'понедельник';

Страницы: 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 Больше тэгов
Учебник обновлялся
несколько дней назад
обмен с contact
©SQL-EX,2008 [Развитие] [Связь] [О проекте] [Ссылки] [Team]
Перепечатка материалов сайта возможна только с разрешения автора.