loading..
Русский    English
09:36
листать

Первый день недели стр. 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'понедельник';

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