Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Продление периодов по дням  [new]
Nurgle
Guest
есть таблица
в не может быть
-----------------------------------------
Дата Данные
-----------------------------------------
2011-02-05 00:00:00.000 1
2011-02-07 00:00:00.000 2
2011-02-08 00:00:00.000 3
2011-02-11 00:00:00.000 4


нужно получить

2011-02-05 00:00:00.000 1
2011-02-06 00:00:00.000 1
2011-02-07 00:00:00.000 2
2011-02-08 00:00:00.000 3
2011-02-09 00:00:00.000 3
2011-02-10 00:00:00.000 3
2011-02-11 00:00:00.000 4


т.к. промежутки между датами должны быть заполнены по дням и повторением данных
7 сен 12, 16:36    [13131371]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Nurgle
Guest
Nurgle,

Криво я написал совсем устал бошка не варит... нужно чтобы дполнялись интервалы между датами... Данные в других полях в этих интервалах должны замножатся.
На верхнем примере это видно хотя он немного съехал
7 сен 12, 16:57    [13131545]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Nurgle
Guest
АП! Срочно надо!!! иначе сегодняшний вечер пройдет на работе
7 сен 12, 17:13    [13131656]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Nurgle,

Находите MAX и MIN даты, и развивайте код.

-- сделать список дат, от даты начала до даты окончания
DECLARE @date_begin smalldatetime
DECLARE @date_end smalldatetime

SET @date_begin = '20120801'
SET @date_end ='20120814'

;WITH C AS (
SELECT 1 AS N, @date_begin AS DD
UNION ALL
SELECT  N+1, @date_begin + N FROM C WHERE @date_begin + N <= @date_end
)
SELECT * FROM C
7 сен 12, 17:18    [13131681]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Владимир Затуливетер
Member

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

if object_id('tempdb..#Data') is not null 
    begin
        drop table #Data
    end
go
    
create table #Data ( dt datetime2(0) )
go

insert  into #Data ( dt )
values  ( '2011-02-05 00:00:00.000' ) 
,       ( '2011-02-07 00:00:00.000' ) 
,       ( '2011-02-08 00:00:00.000' ) 
,       ( '2012-02-11 00:00:00.000' );

declare @MinDt datetime
declare @CntDay int
select  @MinDt = min(dt)
      , @CntDay = datediff(day, min(dt), max(dt))
from    #Data;

with    cte ( id )
          as ( select   0
               union all
               select   id + 1
               from     cte
               where    id < @CntDay
             )
    select  dateadd(day, id, @MinDt) as Date
    from    cte
option  ( maxrecursion 0 )
7 сен 12, 17:35    [13131793]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
как находить периоды вот тут, например, можно подсмотреть тынц
7 сен 12, 17:38    [13131810]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
nezhadnye_my
Guest
заполнить дыры можно и без рекурсии, хватит таблицы чисел.
а продлить значения сразу не соображу и тоже с работы убегаю.
если никто до вечера не ответит, может из дома напишу.

declare @t table (dt datetime, val int)
insert into @t values('20110205', 1), ('20110207', 2),('20110208', 3),('20110211', 4)

declare @min_date datetime = (select MIN(dt) from @t)
declare @max_date datetime = (select MAX(dt) from @t)
declare @n_days int = datediff(DD, @min_date, @max_date) 

;with cte as(
select dateadd(dd, number, @min_date) as dt
from master..spt_values
where type = 'P' and number <= @n_days)

select c.dt, t.val
from cte c left join @t t on c.dt = t.dt


dt                      val
----------------------- -----------
2011-02-05 00:00:00.000 1
2011-02-06 00:00:00.000 NULL
2011-02-07 00:00:00.000 2
2011-02-08 00:00:00.000 3
2011-02-09 00:00:00.000 NULL
2011-02-10 00:00:00.000 NULL
2011-02-11 00:00:00.000 4
7 сен 12, 17:48    [13131894]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
aleks2
Guest
declare @t table (dt datetime, val int)
insert into @t values('20110205', 1), ('20110207', 2),('20110208', 3),('20110211', 4)

;with
n as (select *, ROW_NUMBER() over(order by dt asc) n from @t)
select DATEADD(DAY, n1.val, n1.dt) as dt, DATEDIFF(DAY, n1.dt, n2.dt)-n1.val as val
  from n n1 inner join n n2 on n1.n+1 = n2.n where n2.dt > DATEADD(DAY, n1.val, n1.dt)
union all
select * from @t
order by 1;
7 сен 12, 18:06    [13132018]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Nurgle
Guest
рузультат последнего запроса который запостили
dt	                               val
2011-02-05 00:00:00.000	1
2011-02-06 00:00:00.000	1
2011-02-07 00:00:00.000	2
2011-02-08 00:00:00.000	3
2011-02-11 00:00:00.000	4


косяк ))))
потомучто должно быть так
dt	                               val
2011-02-05 00:00:00.000	1
2011-02-06 00:00:00.000	1
2011-02-07 00:00:00.000	2
2011-02-08 00:00:00.000	3
2011-02-09 00:00:00.000      3
2011-02-10 00:00:00.000      3
2011-02-11 00:00:00.000	4
7 сен 12, 18:13    [13132054]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Nurgle
Guest
ап
7 сен 12, 18:50    [13132216]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Владимир Затуливетер
Member

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

вам еще и числа нужны.... :)

if object_id('tempdb..#Data') is not null 
    begin
        drop table #Data
    end
go
    
create table #Data ( dt datetime2(0) )
go

insert  into #Data ( dt )
values  ( '2011-02-05 00:00:00.000' ) 
,       ( '2011-02-07 00:00:00.000' ) 
,       ( '2011-02-08 00:00:00.000' ) 
,       ( '2011-02-11 00:00:00.000' );

declare @MinDt datetime
declare @CntDay int
select  @MinDt = min(dt)
      , @CntDay = datediff(day, min(dt), max(dt))
from    #Data;

with cteData 
		as (
			select dt, row_number() over (order by dt) as RowNum
			from #Data
		) ,
	    cte ( id )
          as ( select   0
               union all
               select   id + 1
               from     cte
               where    id < @CntDay
             )
    select  dateadd(day, id, @MinDt) as Date, RowNum
    from    cte	
		outer apply ( select max(rowNum) as RowNum
					  from cteData
					  where dt <= dateadd(day, id, @MinDt) 
					) dd
option  ( maxrecursion 0 )
7 сен 12, 19:00    [13132249]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Nurgle
Guest
я как пример один столбец с цифрами показал на самом деле все хуже там не просто числа а 10 столбцов и float и nvarchar и чего только там нет ))))
Так что ваш запрос не совсем подходит
7 сен 12, 19:06    [13132259]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
Владимир Затуливетер
Member

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

Надо привести полностью задачу, это все решается.
Но боюсь сегодня вам уже никто не поможет.

Как вариант можно сделать так.

(вот эти таблицы генегирм или если мало значений забиваем через union all)
таблица значений для столбца 1
таблица значений для столбца 2
...
таблица значений для столбца N

после

все это джойним через full join
далее left outer join ВашаГлавная таблица
и будет вам без пропусков
потом остается номерки поставить, но это уже после :)
7 сен 12, 19:12    [13132275]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
А если так?
Guest
declare @MaxDate date
         ,@MinDate date

select @MaxDate = max(date) 
       ,@MinDate = min(date)
  from OurTable
 
;with cte as
(Select  date,otherdata
   from OurTable
  where date = @MinDate
 union all
 select dateadd(dd,1,cte.date),isnull(o.otherdata,cte.otherdata)
   from cte
   left join OurTable o on o.date = dateadd(dd,1,cte.date)
 where cte.date<@MaxDate)
option(maxrecursion 0)
7 сен 12, 19:46    [13132391]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
промазал малясь
Guest
А если так?,

там бы еще селект * фром цте забахать :)
нечем проверить
7 сен 12, 19:48    [13132404]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
aleks2
Guest
Nurgle
рузультат последнего запроса который запостили


Извиняй, дарагуля, так "как надо" я тоже могу, но всеж мне лень занисаться сей мартышкиной работой.
Сообрази ужо сам.
7 сен 12, 20:06    [13132482]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
ВотКосяк
Guest
А если так?,
таки нельзя в рекурсивной части outer join использовать...
7 сен 12, 20:41    [13132559]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
nezhadnye_my
Guest
declare @t table (dt datetime, val int)
insert into @t values('20110205', 1), ('20110207', 2),('20110208', 3),('20110211', 4)

declare @min_date datetime = (select MIN(dt) from @t)
declare @max_date datetime = (select MAX(dt) from @t)
declare @n_days int = datediff(DD, @min_date, @max_date) 

;with cte as(
select dateadd(dd, number, @min_date) as dt
from master..spt_values
where type = 'P' and number <= @n_days)

,cte1 as(
select c.dt, t.val
from cte c left join @t t on c.dt = t.dt)

select c.dt,
       isnull(c.val,(select top 1 t.val from @t t where t.dt < c.dt order by t.dt desc)) as val
from cte1 c
7 сен 12, 20:55    [13132615]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
А если так?
Guest
Раз уж накосячил, надо исправляться)
if object_ID('OurTable') is not null
  drop table OurTable

create table OurTable
(Dt date
,OtherData varchar(10))

insert OurTable values('2011-01-11','11')
insert OurTable values('2011-01-13','13')
insert OurTable values('2011-01-14','14')
insert OurTable values('2011-01-18','18')


declare @MaxDate date
       ,@MinDate date
	   ,@days int

select @MinDate = min(dt)
	  ,@days    = datediff(dd,min(dt),max(dt))
  from OurTable
 
;with a as
(select * from(values(1),(2))a(a))
, b as(select a.a from a,a b)
, c as(select b.a from b,b c)
, d as(select c.a from c,c d)
, e as(select row_number()over(order by(select 1))-1 r from d,d e)
select dateadd(dd,r,@MinDate),OtherData
  from e
  cross apply(select top 1 OtherData 
                from OurTable
			   where dt<=dateadd(dd,r,@MinDate)
			   order by dt desc)d
 where r<=@days
7 сен 12, 20:58    [13132627]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
nezhadnye_my
Guest
о, какие тут подробности про другие столбцы.
ну, мое под это переделывается, хотя, простите, это полная ж..а

данные:
dt	val	val_char
2011-02-05 00:00:00.000	1	kaka
2011-02-07 00:00:00.000	2	koka
2011-02-08 00:00:00.000	3	kuka
2011-02-11 00:00:00.000	4	kisa


declare @t table (dt datetime, val int, val_char varchar(10))
insert into @t values('20110205', 1, 'kaka'), ('20110207', 2, 'koka'),('20110208', 3, 'kuka'),('20110211', 4, 'kisa')

declare @min_date datetime = (select MIN(dt) from @t)
declare @max_date datetime = (select MAX(dt) from @t)
declare @n_days int = datediff(DD, @min_date, @max_date) 

;with cte as(
select dateadd(dd, number, @min_date) as dt
from master..spt_values
where type = 'P' and number <= @n_days)

,cte1 as(
select c.dt, t.val, val_char
from cte c left join @t t on c.dt = t.dt)

select c.dt,
       isnull(c.val,(select top 1 t.val from @t t where t.dt < c.dt order by t.dt desc)) as val,
       isnull(c.val_char,(select top 1 t.val_char from @t t where t.dt < c.dt order by t.dt desc)) as val_char
from cte1 c


dt	val	val_char
2011-02-05 00:00:00.000	1	kaka
2011-02-06 00:00:00.000	1	kaka
2011-02-07 00:00:00.000	2	koka
2011-02-08 00:00:00.000	3	kuka
2011-02-09 00:00:00.000	3	kuka
2011-02-10 00:00:00.000	3	kuka
2011-02-11 00:00:00.000	4	kisa
7 сен 12, 21:12    [13132655]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
OuterApplyInsteadOfSubquery
Guest
nezhadnye_my,
несколько однотипных подзапросов в Вашем случае вполне можно заменить на один outer apply
7 сен 12, 21:38    [13132740]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
nezhadnye_my
Guest
точно-точно.
итого:
declare @t table (dt datetime, val int, val_char varchar(10))
insert into @t values('20110205', 1, 'kaka'), ('20110207', 2, 'koka'),('20110208', 3, 'kuka'),('20110211', 4, 'kisa')

declare @min_date datetime = (select MIN(dt) from @t)
declare @max_date datetime = (select MAX(dt) from @t)
declare @n_days int = datediff(DD, @min_date, @max_date) 

;with cte as(
select dateadd(dd, number, @min_date) as dt
from master..spt_values
where type = 'P' and number <= @n_days)

,cte1 as(
select c.dt, t.val, val_char
from cte c left join @t t on c.dt = t.dt)

select c.dt,
       isnull(c.val, a.val) as val,
       isnull(c.val_char, a.val_char) as val_char
from cte1 c outer apply (select top 1 t.* from @t t where t.dt < c.dt order by t.dt desc) a
7 сен 12, 23:37    [13133090]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
и еще шажок
Guest
nezhadnye_my,
А если теперь в outer applly поменять неравенство на нестрогое, то можно outer заменить на cross
И убрать лишние isnull. И упростить cte
8 сен 12, 00:02    [13133168]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
nezhadnye_my
Guest
как упростить cte не вижу, вроде и так проще некуда.
иду спать, всем спок. ночи :P
вот, по просьбам трудящихся:

declare @t table (dt datetime, val int, val_char varchar(10))
insert into @t values('20110205', 1, 'kaka'), ('20110207', 2, 'koka'),('20110208', 3, 'kuka'),('20110211', 4, 'kisa')

declare @min_date datetime = (select MIN(dt) from @t)
declare @max_date datetime = (select MAX(dt) from @t)
declare @n_days int = datediff(DD, @min_date, @max_date) 

;with cte as(
select dateadd(dd, number, @min_date) as dt
from master..spt_values
where type = 'P' and number <= @n_days)

,cte1 as(
select c.dt, t.val, val_char
from cte c left join @t t on c.dt = t.dt)

select c.dt, a.val, a.val_char
from cte1 c cross apply (select top 1 t.* from @t t where t.dt <= c.dt order by t.dt desc) a
8 сен 12, 00:15    [13133201]     Ответить | Цитировать Сообщить модератору
 Re: Продление периодов по дням  [new]
упростить цте
Guest
nezhadnye_my,
Когда нечего упрощать, можно удалять.
цте1 там совсем ни к чему теперь
8 сен 12, 12:47    [13133677]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить