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

Откуда: Israel
Сообщений: 5500
Не могу сообразить как точнее обозначить тапик. Простите...
Задача. Есть таблица с периодом от и до

;
with
stm (StartDt, EndDt)
as (
	select '2015-03-26 07:00:00' as StartDt, '2015-03-26 08:00:00' as EndDt
	union
	select '2015-03-26 23:00:00', '2015-03-27 02:00:00'
	union
	select '2015-03-26 15:00:00', '2015-03-26 20:00:00'
	union
	select '2015-03-26 13:15:00', '2015-03-28 09:45:00'

)

т.е.

StartDt EndDt
26/03/2015 07:00 26/03/2015 08:00
26/03/2015 13:15 28/03/2015 09:45
26/03/2015 15:00 26/03/2015 20:00
26/03/2015 23:00 27/03/2015 02:00


Получить надо запросом
StartDt EndDt
26/03/2015 07:00 26/03/2015 08:00
26/03/2015 13:15 26/03/2015 23:59
27/03/2015 00:00 28/03/2015 23:59
28/03/2015 00:00 28/03/2015 09:45
26/03/2015 15:00 26/03/2015 20:00
26/03/2015 23:00 26/03/2015 23:59
27/03/2015 00:00 27/03/2015 02:00


Т.е. если EndDt не совпадает с днем StartDt, в текущей строку заменить EndDt на конец дня и добавить строку, начитающуюся с начала следующего дня. Если этот следующий день совпадает с днем EndDt, то EndDt = EndDt, иначе, см выше...
Надеюсь, внятно объяснил...
30 мар 15, 12:12    [17449215]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Glory
Member

Откуда:
Сообщений: 104751
Rivkin Dmitry
Т.е. если EndDt не совпадает с днем StartDt, в текущей строку заменить EndDt на конец дня и добавить строку, начитающуюся с начала следующего дня. Если этот следующий день совпадает с днем EndDt, то EndDt = EndDt, иначе, см выше...
Надеюсь, внятно объяснил...

Берете таблицу-календарь со всеми датами и соединяете ее со своим набором
30 мар 15, 12:14    [17449226]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Rivkin Dmitry
Member

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

Я, собственно, так и пытался. Но что-то не преуспел. Видать, мозги ржавеють...
Не покажете ли как это сделать?
30 мар 15, 12:20    [17449247]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Glory
Member

Откуда:
Сообщений: 104751
Rivkin Dmitry
Я, собственно, так и пытался. Но что-то не преуспел. Видать, мозги ржавеють...
Не покажете ли как это сделать?

from calendar a join mytable b on a.dt between b.StartDt and b.EndDt
30 мар 15, 12:21    [17449253]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Rivkin Dmitry
Member

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

не то....
30 мар 15, 12:27    [17449279]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Glory
Member

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

не то....

Ну конечно
30 мар 15, 12:30    [17449290]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21243
Ну если схематичненько, то типа
SELECT
CASE WHEN mytable.StartDt > calendar.date THEN mytable.StartDt ELSE calendar.date END,
CASE WHEN mytable.EndDt > calendar.date THEN mytable.EndDt ELSE calendar.date + '23:59:59' END
FROM calendar, mytable
WHERE calendar.date BETWEEN CAST(mytable.StartDt AS DATE) AND CAST (mytable.EndDt AS DATE)
30 мар 15, 13:02    [17449528]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
o-o
Guest
;
with
stm (StartDt, EndDt)
as (
	select '2015-03-26 07:00:00' as StartDt, '2015-03-26 08:00:00' as EndDt
	union
	select '2015-03-26 23:00:00', '2015-03-27 02:00:00'
	union
	select '2015-03-26 15:00:00', '2015-03-26 20:00:00'
	union
	select '2015-03-26 13:15:00', '2015-03-28 09:45:00'

)

select StartDt, 
       case when datediff(DAY, cast(StartDt as date), cast(EndDt as date)) < 1 
            then EndDt
       else dateadd(minute, -1, cast(dateadd (day, 1, cast(StartDt as date)) as datetime)) 
       end as EndDt
from stm

union all

select  cast(dateadd(day, a.n, cast(StartDt as date)) as datetime),
        case when s.EndDt < dateadd(minute, -1, dateadd (day, n, cast(dateadd(day, a.n, cast(StartDt as date)) as datetime)))
             then s.EndDt
             else dateadd(minute, -1, dateadd (day, n, cast(dateadd(day, a.n, cast(StartDt as date)) as datetime)))
        end     
from stm s cross apply  (select top(DATEDIFF(day, s.StartDt, s.EndDt)) * 
                         from dbo.nums )a 
where cast(s.StartDt as date) < cast(s.EndDt as date)
30 мар 15, 13:27    [17449725]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Rivkin Dmitry
Member

Откуда: Israel
Сообщений: 5500
Akina,

Да! Очень близко. Спасибо!
На самом деле равенства

select 
case when convert(nvarchar(10), StartDt, 120) = dt then StartDt else dt end as StartDt,
case when convert(nvarchar(10), EndDt, 120) = dt then EndDt else dateadd(second, -1, dt + 1) end EndDt
from #cal a, stm b 
where dt between convert(nvarchar(10), StartDt, 120) and convert(nvarchar(10), EndDt, 120)
30 мар 15, 13:30    [17449748]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21243
Rivkin Dmitry
На самом деле равенства

Нет. У тебя выпадут "серединки", если разница между датами периода более 1 дня.
30 мар 15, 13:43    [17449820]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21243
Или не выпадут... фиг с им, лениво думать.
30 мар 15, 13:44    [17449826]     Ответить | Цитировать Сообщить модератору
 Re: Разложить дату по дням  [new]
Rivkin Dmitry
Member

Откуда: Israel
Сообщений: 5500
Akina,

Вроде, работает...
30 мар 15, 14:23    [17450063]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить