伙计我有这张桌子
+--------------------+------+
|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 :(得分: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
答案 1 :(得分: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)
我们创建了一个名为times
的CTE,它可以找到最小和最大stime
值之间的所有分钟。然后,我们尝试将两个连接返回到原始表,其中的注释指示这两个连接尝试查找的内容。然后,我们在WHERE
子句中消除t_2
连接成功的所有行 - 这是t_1
连接从表中找到最匹配行的确切行。
option (maxrecursion 0)
只是允许CTE与更广泛的输入值一起使用,其中生成所有stime
值可能需要大量递归。
答案 2 :(得分: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
答案 3 :(得分: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