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

Откуда:
Сообщений: 23
Добрый день.

Прошу помощи знающих людей.

Стандартная фраза, с которой начинается обращение: "...если я плохо искал по форуму, просьба ткнуть меня носом в тему" :)

Задача такова, что имеем SQL Server 2008 R2, с пустой базой, в которой будет проводиться всякая аналитика. Для некоторых процедур, которые будут работать в курсоре, необходимы переменные, т.е. Дата начала и Дата конечная.

Поэтому, имеем
@dt1 = '01/01/2013' --Январь
@dt2 = '12/05/2013' --Декабрь

Нужно получить либо таблицу, либо временную таблицу, либо просто данные (дни между указанными датами) типа:
01/01/2013
02/01/2013
03/01/2013
...
и т.д. до 05 декабря 2013 года.

Может кто-то подсказать простое или не очень простое решение этой задачки?

Спасибо.

С уважением к форуму...
5 дек 13, 15:11    [15246963]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
Glory
Member

Откуда:
Сообщений: 104751
Artemy_ch
Может кто-то подсказать простое

Сделать таблицу-календарь на 10-20-30... лет вперед
5 дек 13, 15:16    [15246997]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
Artemy_ch
Member

Откуда:
Сообщений: 23
Видимо к этому все и идет, чтобы создать таблицу -календарь.

Понравилась табличка с данными в этой теме: Помощь в решении задачи

Но вот как это реализовать, готового решения не нашел.

Пробовал и другие запросы с этого форума, типа:
declare @t table(id int, Start_date datetime, End_date datetime)
insert into @t values(1,'20130101','20130201'),(2,'20130101','20130201')

;with buff (id,Start_date,End_date) as 
(select id,Start_date,dateadd(dd,1,Start_date) as End_date from @t
union all 
select  b.id, b.End_date as start_date, dateadd(dd,1,b.End_date) as End_date
from buff b
join @t t on t.id = b.id
and t.End_date >= b.End_date
) select * from buff order by id,Start_date


но ничего хорошего у меня не вышло. Скорее всего не в ту сторону смотрю или как всегда ищу сложные пути решения. :(

Если у кого есть текст запроса по заполнению/созданию этого календаря, буду признателен за информацию.

Спасибо.

С уважением.
5 дек 13, 15:47    [15247231]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3754
Artemy_ch
Добрый день.

Прошу помощи знающих людей.

Стандартная фраза, с которой начинается обращение: "...если я плохо искал по форуму, просьба ткнуть меня носом в тему" :)

Задача такова, что имеем SQL Server 2008 R2, с пустой базой, в которой будет проводиться всякая аналитика. Для некоторых процедур, которые будут работать в курсоре, необходимы переменные, т.е. Дата начала и Дата конечная.

Поэтому, имеем
@dt1 = '01/01/2013' --Январь
@dt2 = '12/05/2013' --Декабрь

Нужно получить либо таблицу, либо временную таблицу, либо просто данные (дни между указанными датами) типа:
01/01/2013
02/01/2013
03/01/2013
...
и т.д. до 05 декабря 2013 года.

Может кто-то подсказать простое или не очень простое решение этой задачки?

Спасибо.

С уважением к форуму...

если скорость не критична (а раз у тебя там курсор - то не критична :))
то просто цикл... while
где добавляешь к начальной дате по 1 дню.
5 дек 13, 18:14    [15248607]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
Ivan Durak
Member

Откуда: Minsk!!!
Сообщений: 3754
но предзаготовленная таблица дат - best practice
5 дек 13, 18:14    [15248610]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
o-o
Guest
declare @dt1 date = '20130101', 
        @dt2 date = '20130512';

with num as 
(
select 100 * l + 10 * m + n as n
from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))t1(l) cross join
     (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))t2(m) cross join
     (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))t3(n)
where 100 * l + 10 * m + n <= datediff(DD, @dt1, @dt2)     
)

select dateadd(dd, n, @dt1) as dt
from num
order by dt


но, как тут 100 раз сказали, чем все время генерить,
заполнить себе заранее и не париться.
хотя бы таблицу чисел себе завести постоянную
5 дек 13, 18:32    [15248712]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
Virtuoz
Member

Откуда: Украина
Сообщений: 307
Я бы применил рекурсию, зная диапазоны дат:

Declare @dt1 datetime = '2013-01-01';
Declare @dt2 datetime = '2013-05-12';

WITH cte_dt_ranges
 AS
    (
    
       SELECT cast(@dt1 as datetime) as DateValue 
         UNION ALL
       SELECT DateValue + 1
         FROM cte_dt_ranges
         WHERE DateValue + 1  <  cast(@dt2 as datetime)  
    )
select * from cte_dt_ranges
OPTION (MAXRECURSION 0);
5 дек 13, 19:22    [15248908]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31983
Virtuoz
Я бы применил рекурсию, зная диапазоны дат:
Это всё равно что вместо сложения двух чисел писать циклы по битам. Некрасиво.
5 дек 13, 19:40    [15248970]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31983
Artemy_ch
Если у кого есть текст запроса по заполнению/созданию этого календаря, буду признателен за информацию.
Календарь заполняется один раз в жизни. Зачем искать красивый код??? Заполните как нибуть, циклами, например, и забудьте.
5 дек 13, 19:42    [15248978]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
o-o
Guest
Virtuoz,
посчитаем обоими способами за 2 года?
статистики ради

+
set statistics time on;
set statistics io on;


declare @dt1 date = '20100101', 
        @dt2 date = '20120101';
        
print 'o_o';

with num as 
(
select 100 * l + 10 * m + n as n
from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))t1(l) cross join
     (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))t2(m) cross join
     (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9))t3(n) 
where 100 * l + 10 * m + n <= datediff(DD, @dt1, @dt2)     
)

select dateadd(dd, n, @dt1) as dt
from num
order by dt
----------------------------------------------------------
print 'Virtuoz';

WITH cte_dt_ranges
 AS
    (
    
       SELECT cast(@dt1 as datetime) as DateValue 
         UNION ALL
       SELECT DateValue + 1
         FROM cte_dt_ranges
         WHERE DateValue + 1  <  cast(@dt2 as datetime)  
    )
select * from cte_dt_ranges
OPTION (MAXRECURSION 0);
-----------------------------------------------------------
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
o_o

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(731 row(s) affected)

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
Virtuoz

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(730 row(s) affected)
Table 'Worktable'. Scan count 2, logical reads 4382, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 67 ms.




зато рекурсия звучит гордо :)
кстати, при выводе статистики обнаружилось,
что Вы конечную дату теряете.

но для курсоров сойдет хоть как :)
5 дек 13, 19:45    [15248994]     Ответить | Цитировать Сообщить модератору
 Re: Запрос всех дней между двумя датами (некий календарь дней)  [new]
Artemy_ch
Member

Откуда:
Сообщений: 23
Спасибо всем огромное за участие. Подобрал функцию, которая выводит даты и заполнил таблицу-календарь. На всякий случай, а случаи бывают разные, оставил запрос с получением дат в моменте...

Еще раз всех благодарю!

С уважением...
6 дек 13, 16:51    [15254595]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить