2014-01-13 143 views
4

傢伙,我有這個表填補缺失值

+--------------------+------+ 
|stime (datetime) |svalue| 
+--------------------+------+ 
|1/13/2014 8:40:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:45:00 AM|6  | 
+--------------------+------+ 
|1/13/2014 8:46:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:50:00 AM|4  | 
+--------------------+------+ 

難道在MSSQL可以創建一個查詢了所有的資料有1分鐘的間隔,如果日期不存在,它取第一下的數據(WHERE stime <=)的值和值分配給時間

所以結果我試圖讓應該是這樣的:

+--------------------+------+ 
|stime (datetime) |svalue| 
+--------------------+------+ 
|1/13/2014 8:40:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:41:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:42:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:43:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:44:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:45:00 AM|6  | 
+--------------------+------+ 
|1/13/2014 8:46:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:47:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:48:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:49:00 AM|5  | 
+--------------------+------+ 
|1/13/2014 8:50:00 AM|4  | 
+--------------------+------+ 

提前感謝!

+0

在這之前你有沒有嘗試過任何東西? –

+1

對於「第二」,我們是否應該閱讀「分鐘」?此外,這是爲特定查詢更改*結果集*,還是試圖永久更改其表中的數據? –

+0

是的,我的意思是分鐘抱歉 – user3182508

回答

6

可以使用CTE產生從MIN(stime)MAX(stime)時間序列:

WITH TMinMax as 
(
    SELECT MIN(stime) as MinTime, 
      MAX(stime) as MaxTime 
    FROM T 
) 
,CTE(stime) as 
(
    SELECT MinTime FROM TMinMax 
    UNION ALL 
    SELECT DATEADD(minute,1, stime) 
    FROM CTE 
    WHERE DATEADD(minute,1, stime)<= 
      (SELECT MaxTime from TMinMax) 

) 
select stime, 
     (SELECT TOP 1 svalue 
      FROM T 
      WHERE stime<=CTE.Stime 
     ORDER BY stime DESC) as svalue 
from CTE 
ORDER BY stime 

SQLFiddle demo

+0

非常感謝! – user3182508

0
> DECLARE @stime INT 
SET @stime= (select min(stime) from table group by stime) 
WHILE (@stime <=(select max(stime) from table group by stime)) 
BEGIN 
IF (@stime IN (select stime from table)) 
    begin 
     select stime,svalue from table where stime = @stime 
    end 
ELSE 
    begin 
     select @stime,svalue from table where stime = (select min(stime) from table group by stime) 
    end 

SET @stime = @stime + 1 
END 
GO 
0

試試這個

use tempdb 
go 
/* you need to create this table once and fill it with all necesaary dates */ 
create table dbo.tblSeconds (s datetime) 

declare @s datetime='20140101' 

WHILE @s<'20140102' 
    begin 
     insert into dbo.tblSeconds (s) values (@s) 

     set @s=DATEADD(SECOND,1,@s) 
    end 


create table dbo.YourTable (s datetime, strValue int) 

insert into dbo.YourTable (s,strValue) values('20140101',0),('20140101 05:00',3),('20140101 07:01',5) 


select s.s, (select top(1) t.strValue from dbo.YourTable t where t.s<=s.s order by t.s desc) strValue 
from dbo.tblSeconds s 
order by s.s 

drop table dbo.tblSeconds 
drop table dbo.YourTable 
1

這似乎做的工作:

declare @t table (stime datetime,svalue int) 
insert into @t(stime,svalue) values 
('2014-01-13T08:40:00',5), 
('2014-01-13T08:45:00',6), 
('2014-01-13T08:46:00',5), 
('2014-01-13T08:50:00',4) 

;with times as (
    select MIN(stime) as stime,MAX(stime) as etime from @t 
    union all 
    select DATEADD(minute,1,stime),etime from times where stime < etime 
) 
select 
    t.stime,t_1.svalue 
from 
    times t 
     left join 
    @t t_1 
     on 
      t.stime >= t_1.stime --Find an earlier or equal row 
     left join 
    @t t_2 
     on 
      t.stime >= t_2.stime and --Find an earlier or equal row 
      t_2.stime > t_1.stime --That's a better match than t_1 
where 
    t_2.stime is null --Second join fails 
order by t.stime 
option (maxrecursion 0) 

我們創建了一個名爲CTE是times找出所有的最小值和最大值stime值之間的分鐘。然後,我們嘗試將兩個連接返回到原始表,並使用註釋指出這兩個連接嘗試查找的內容。然後,我們在WHERE子句中刪除任何連接成功的行,這些行是t_1連接找到表中匹配最佳行的確切行。

option (maxrecursion 0)只是爲了允許CTE與更廣泛的輸入值一起使用,其中生成所有stime值可能需要大量的遞歸。