Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Запрос хитренький / 10 сообщений из 10, страница 1 из 1
02.10.2001, 13:54
    #32014800
Андрей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
Есть табличка каждая запись которой содержит некоторые даты начала и конца периода. Нужно чтобы запрос выводил КАЖДУЮ дату в периоде.
Например в табличке содержится 01.01.2001 начало периода и 30.06.2001 конец периода. Запрос должен сгенерить нное количество записей на каждый день в периоде. Приблизительно так.
01.01.2001
02.01.2001
03.01.2001
...
01.06.2001
02.06.2001
...
30.06.2001

Возможно ли такое сделать единтсвенным запросом. Если да то как. Использую для работы MSSQL 7.


С уважением. Андрей
...
Рейтинг: 0 / 0
02.10.2001, 17:27
    #32014820
cvasil
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
Первое что пришло на ум - сделать дополнительную табличку и забить в нее все дни для необходимого периода времени. Insert statements с датами для простоты можно сгенерить например экселем.

create table days (d datetime primary key)
-- 2001 год
insert into days values('20010101')
insert into days values('20010102')
...
insert into days values('20011231')
insert into days values('20020101')

После чего можно использовать эту табличку для получения необходимых Вам данных:

declare @begin_date datetime, @end_date datetime
set @begin_date = '20010110'
set @end_date = '20010120'
select d from days where d between @begin_date and @end_date
...
Рейтинг: 0 / 0
02.10.2001, 19:28
    #32014826
Андрей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
не годится. Суть в том чтобы автоматом пополнялся список дат по мере появления новых периодов. Нужно одним запросом. Рекурсивно. Ежели бы знал как , не спрашивал. До MSSQL не сильно обшщался с DB/2 так на ее диалекте это запросто. А тут ни как.
...
Рейтинг: 0 / 0
02.10.2001, 19:55
    #32014831
cvasil
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
Ну тогда можно процедуркой сделать:

create proc dates (@begin_date datetime, @end_date datetime)
as
if @begin_date > @end_date
begin
raiserror ('Incorrect order of the dates', 1, 0)
return 1
end
create table #d_temp(d datetime)
set nocount on
while @begin_date <= @end_date
begin
insert #d_temp values(@begin_date)
select @begin_date = @begin_date + 1
end
set nocount off
select d from #d_temp
return 0

Правда работать будет немного медленнее.
...
Рейтинг: 0 / 0
02.10.2001, 20:04
    #32014832
Андрей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
Ну я же говорю, что не нужно процедурой. Нужно одним запросом. Из этого запроса будет сделан вьюв из которого в свою очередь другой вьюв итд итп. Не нужно процедур.

Андрей
...
Рейтинг: 0 / 0
03.10.2001, 05:44
    #32014850
Denis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
К сожалению в MSSQL рекурсивных запросов не бывает ;(

Следует создать вторую таблицу с днями, и заполнять ее в триггере на вставку и изменение данных в первой таблице.
Можно было бы обойтись и без этого если бы размер периода был ограничен сверху, например, не больше 31 дня.

Тогда:
SELECT begin_date FROM periods WHERE begin_date BETWEEN begin_date AND end_date
UNION SELECT DATEADD(d, 1, begin_date) FROM periods WHERE DATEADD(d, 1, begin_date) BETWEEN begin_date AND end_date
UNION SELECT DATEADD(d, 2, begin_date) FROM periods WHERE DATEADD(d, 2, begin_date) BETWEEN begin_date AND end_date
...
UNION DATEADD(d, 31, begin_date) FROM periods WHERE DATEADD(d, 31, begin_date) BETWEEN begin_date AND end_date

естественно если максимальный размер периода = 1 году строк должно быть 367
...
Рейтинг: 0 / 0
03.10.2001, 06:08
    #32014856
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
В принципе я согласен с Denis-ом, но не понял что он написал и причем тут триггеры.
У лично меня для таких случаев есть такая таблица:
CREATE TABLE Millenium (num int)
в ней 1000 строчек просто с числами от 0 до 999.
Тогда запрос получается простой:
declare @d1 datetime, @d2 datetime
select @d1='20010101',@d2='20010630'
select dateadd(dd,num,@d1)
from Millenium
where num<=datediff(dd,@d1,@d2)

если чисел больше чем 1000 то можно или увеличить число строк в таблице Millenium или написать как-то так (думаю уж 3000 лет будет достаточно ) :
declare @d1 datetime, @d2 datetime
select @d1='20010101',@d2='20010630'
select dateadd(dd,m1.num*1000+m2.num,@d1)
from Millenium m1,Millenium m2
where m1.num*1000+m2.num<=datediff(dd,@d1,@d2)

С приветом Сергей
...
Рейтинг: 0 / 0
03.10.2001, 06:25
    #32014859
Denis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
2SuperSerg про триггер я перестарался, имелось в виду в нем заполянть таблицу с датами заполняющими все периоды таблицы периодов (см. выше предложение cvasil) - бред. ;(
Твоя метода принципиально проще и вернее.
Сам пользовался этим приемом для размножения строк в результатах запросов, а тут заклинило...
...
Рейтинг: 0 / 0
03.10.2001, 07:03
    #32014867
Запрос хитренький
Ну, если нужно одним запросом, то можно применить такое решение:

Исходное: табличка Periods (Id int, MinDate datetime, MaxDate datetime)
Нужно: один запрос, содержащий без разрыва списки дат между MinDate и MaxDate.

Решение:

select p.Id IdPeriod, p.MinDate+SetOfNums.Num Dates
from Period p,
(select d3.Digit*100+d2.Digit*10+d1.Digit Num
from
(select 0 Digit
union select 1
union select 2
union select 3
union select 4
union select 5
union select 6
union select 7
union select 8
union select 9) as d1,
(select 0 Digit
union select 1
union select 2
union select 3
union select 4
union select 5
union select 6
union select 7
union select 8
union select 9) as d2,
(select 0 Digit
union select 1
union select 2
union select 3
union select 4
union select 5
union select 6
union select 7
union select 8
union select 9) as d3) SetOfNums
where p.MinDate+SetOfNums.Num<=p.MaxDate
order by 1,2
...
Рейтинг: 0 / 0
04.10.2001, 07:55
    #32014951
Андрей
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос хитренький
Спасибо. Последний вариант то что нужно.
Оказалось все очень просто.

С уважением, Андрей Ковешников
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Запрос хитренький / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]