Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Datediff для недели и начало недели  [new]
eXeLe
Member

Откуда:
Сообщений: 65
Столкнулся с ситуацией, которою не могу понять.

Задаю начало недели с понедельника:
set datefirst 1

Смотрим номер недели для трех дат:
SELECT DATEPART(wk,'01.01.2012')
SELECT DATEPART(wk,'02.01.2012')
SELECT DATEPART(wk,'08.01.2012')

Для 01.01.2012 - первая неделя (воскресенье), для двух других - вторая (понедльник и вторник).

Дальше пробую DATEDIFF (чтоб потом получить даты начала и конца недели):
SELECT DATEDIFF(wk,0,'01.01.2012')
SELECT DATEDIFF(wk,0,'02.01.2012')
SELECT DATEDIFF(wk,0,'08.01.2012')

и тут уже для первых двух дат - одно значение, для последней - другое.

Соответственно, если попробовать найти начало недели для 01.01.2012:
SELECT DATEADD(wk,DATEDIFF(wk,0,'01.01.2012'),0)

То выдаст начало недели - 02.01.2012.
25 ноя 14, 17:53    [16903825]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
o-o
Guest
eXeLe,

прикольно.
по-моему, это называется "загнать в угол".
вы просите сервер назвать первый день (понедельник!!!) первой недели года 2012,
а там вообще 20120101 -- это воскресенье.
соответственно, вы бы на месте сервера что выдали?
он выдал ближайший понедельник к 20120101, т.е. 20120102,
а вы бы предпочли 20111226?
но ведь это не "первая неделя года 2012", а "последняя неделя 2011"
для остальных дат аномалия не проявляется, т.к. для них неделя началась в 2012-ом году
25 ноя 14, 18:25    [16904036]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
eXeLe
Member

Откуда:
Сообщений: 65
Уточню, использую:
set language Russian
для верного формата даты в своих примерах.
25 ноя 14, 18:25    [16904037]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
eXeLe
Member

Откуда:
Сообщений: 65
o-o,

понял, не до конца был уверен, как работает это.
каким тогда образом можно вернуть всё же относительное начало недели, без рамок года, то есть 20111226?
25 ноя 14, 18:27    [16904048]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
eXeLe
Member

Откуда:
Сообщений: 65
Имеется ввиду, что может быть существует более простое решение, чем смотреть номер дня дня недели и вычитать его из даты.
25 ноя 14, 19:53    [16904457]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Древний-древний баян: Глюки DATEDIFF или просто жара?
На самом деле ещё более древний.
DATEDIFF(WEEK,@D1,@D2) не зависит от SET DATEFIRST и SET LANGUAGE!!!
25 ноя 14, 20:28    [16904594]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
o-o
Guest
iap,

ну не все же стары, как этот баян
знакомьтесь! Пудинг o-o, это Алиса баян. баян, это o-o.
---
т.к. анализировать "количество переходов с субботы на воскресенье" не хочется,
предлагаю тупо считать, как и было предложено, но если "вылетаем" за исходную дату, прибавлять на неделю меньше.
у кого есть предложения поизящнее, выкладывайте

declare @t table (dt date);  
insert into @t values ('20111225'), ('20111226'), ('20111227'), ('20111231'),
                      ('20120101'), ('20120102'), ('20120108'), ('20120109');

SELECT dt, case when DATEADD(wk, DATEDIFF(WK, 0, dt), 0) > dt 
                then DATEADD(wk, DATEDIFF(WK, 0, dt) - 1, 0)
                else DATEADD(wk, DATEDIFF(WK, 0, dt), 0)
           end as [1st week day]
from @t;
-------
dt	        1st week day
2011-12-25	2011-12-19 00:00:00.000
2011-12-26	2011-12-26 00:00:00.000
2011-12-27	2011-12-26 00:00:00.000
2011-12-31	2011-12-26 00:00:00.000
2012-01-01	2011-12-26 00:00:00.000
2012-01-02	2012-01-02 00:00:00.000
2012-01-08	2012-01-02 00:00:00.000
2012-01-09	2012-01-09 00:00:00.000     
25 ноя 14, 22:43    [16905240]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
Glory
Member

Откуда:
Сообщений: 104751
eXeLe
Имеется ввиду, что может быть существует более простое решение, чем смотреть номер дня дня недели и вычитать его из даты.

Создаете таблицу-календарь, где для каждой даты задаете нужный вам номер недели
26 ноя 14, 00:29    [16905498]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
eXeLe
Member

Откуда:
Сообщений: 65
iap,
да, тоже пробовал вчера с разными SET DATEFIRST, результат для DATEDIFF был тот же (ну не считая общего смещения)

o-o,
Да, работает, спасибо, но я всё же остановился на варианте с вычетом номера дня недели из даты
DATEADD(day,1-weekday_id,date_id)


Glory,
так поверх календаря и строится. Номер недели есть - datepart(wk,date_id). Но обозначенной проблемы это не решало. Ну и сам календарь начинается у меня с 01.01.2012, так что просчитать минимальный день для недели=Х года=Y не вышло бы, да и смотрелось бы криво
26 ноя 14, 10:19    [16906309]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
Glory
Member

Откуда:
Сообщений: 104751
eXeLe
так поверх календаря и строится. Номер недели есть - datepart(wk,date_id). Но обозначенной проблемы это не решало

Еще раз
Создайте в своем календаре поле "Номер недели".
Заполните его один раз.
Забудьте о рассчетах номера недели.
26 ноя 14, 10:21    [16906320]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
eXeLe
Member

Откуда:
Сообщений: 65
Glory,

а мы и не рассчитываем номер недели.
Вопрос был в поиске даты начала недели.
26 ноя 14, 10:29    [16906369]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
aleks2
Guest
o-o
iap,

ну не все же стары, как этот баян
знакомьтесь! Пудинг o-o, это Алиса баян. баян, это o-o.
---
т.к. анализировать "количество переходов с субботы на воскресенье" не хочется,
предлагаю тупо считать, как и было предложено, но если "вылетаем" за исходную дату, прибавлять на неделю меньше.
у кого есть предложения поизящнее, выкладывайте

declare @t table (dt date);  
insert into @t values ('20111225'), ('20111226'), ('20111227'), ('20111231'),
                      ('20120101'), ('20120102'), ('20120108'), ('20120109');

SELECT dt, case when DATEADD(wk, DATEDIFF(WK, 0, dt), 0) > dt 
                then DATEADD(wk, DATEDIFF(WK, 0, dt) - 1, 0)
                else DATEADD(wk, DATEDIFF(WK, 0, dt), 0)
           end as [1st week day]
from @t;
-------
dt	        1st week day
2011-12-25	2011-12-19 00:00:00.000
2011-12-26	2011-12-26 00:00:00.000
2011-12-27	2011-12-26 00:00:00.000
2011-12-31	2011-12-26 00:00:00.000
2012-01-01	2011-12-26 00:00:00.000
2012-01-02	2012-01-02 00:00:00.000
2012-01-08	2012-01-02 00:00:00.000
2012-01-09	2012-01-09 00:00:00.000     


А чаво так замороченно?

declare @t table (dt date);  
insert into @t values ('20111225'), ('20111226'), ('20111227'), ('20111231'),
                      ('20120101'), ('20120102'), ('20120108'), ('20120109');

set datefirst 1;
SELECT dt, DATEADD(day, 1 - DATEPART(dw, dt), dt) as [1st week day]
  from @t;
26 ноя 14, 10:43    [16906471]     Ответить | Цитировать Сообщить модератору
 Re: Datediff для недели и начало недели  [new]
(c)VIG
Member

Откуда:
Сообщений: 1507
Без игр с datefirst

declare @t table (dt date);  
insert into @t values ('20111225'), ('20111226'), ('20111227'), ('20111231'),
                      ('20120101'), ('20120102'), ('20120108'), ('20120109');

select dt, dateadd(d,DATEDIFF(d,'19000101',dt)/7*7,'19000101') as [1st week day]
  from @t;
26 ноя 14, 12:42    [16907280]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить