日期:2014-05-18  浏览次数:20501 次

温度/间隔次数/时间的问题?
表格如下:

id Temp time 
01 101 9:01
01 99 9:03
01 98 9:04
01 95 9:07
01 98 9:09
01 87 9:11
01 88 9:21
01 102 9:23

02 ... ...
02 ... ....
03 ... ...
... ... ...

希望得到两次间隔20分钟以上,温度超过100(中间的温度都低于100,且次数>5)的ID
比如:
ID 01 在 101度的时间是9:01
下一次在102度 的时间是9:23 ,间隔20分钟以上,在此期间温度都小于100,且间隔次数=6>5




------解决方案--------------------
SQL code
create table #t (id varchar(10), Temp float, [time] varchar(5))

insert #t
select '01', 101, '9:01'
union all select '01', 99, '9:03'
union all select '01', 98, '9:04'
union all select '01', 95, '9:07'
union all select '01', 98, '9:09'
union all select '01', 87, '9:11'
union all select '01', 88, '9:21'
union all select '01', 102, '9:23'
union all select '01', 98, '9:25'
union all select '01', 103, '9:38'

create table #tt (id varchar(10), Temp float, [time] smalldatetime)

---------------------------------------------------
SET NOCOUNT ON

Declare @id varchar(10), @Temp float, @time smalldatetime
Declare @status int
Declare @id_0 varchar(10), @Temp_0 float, @time_0 smalldatetime 
Declare @cnt int

Set @id_0 = ''
Set @status = 0  -- 0, not previous record, 1, previous record, not ready, 2, previous record ready
Set @cnt = 0

Declare t_cursor Cursor FOR
SELECT id, Temp, convert(smalldatetime, [time], 108) From #t order by id, convert(smalldatetime, [time], 108)

OPEN t_cursor

Fetch Next From t_cursor
INTO @id, @Temp, @time

WHILE @@Fetch_Status = 0
Begin
    if @id <> @id_0 -- reset everything
    Begin
        if @status= 2  -- insert prevous record
            INsert into #tt select @id_0, @Temp_0, @time_0         
        select @cnt=0, @id_0 = '', @status = 0
    End

    if @Temp > 100 -- temperature satisfied
    Begin
        -- first do the insertion
        if @status > 0 And @cnt > 5 AND Datediff(minute, @time_0, @time)>20 -- good condition
        Begin
            Insert into #tt select @id_0, @Temp_0, @time_0 
            set @status = 2  -- the current record also good
        End            
        Else
        Begin
            if @status = 2     Insert into #tt select @id_0, @Temp_0, @time_0 
            set @status = 1  -- this record not good yet
        End
        select @cnt = 0, @id_0 = @id, @Temp_0 = @Temp, @time_0 = @time -- reset
    END
    ELSE
    Begin -- temperature not satisfied
        if @status > 0 set @cnt = @cnt+1
    End

    FETCH NEXT FROM t_cursor 
    INTO @id, @Temp, @time
End

Close t_cursor
Deallocate t_cursor

if @status = 2
Begin
    INsert into #tt
    select @id_0, @Temp, @time_0 
End
GO
---------------------------------------------

select id, Temp, substring(convert(varchar, time, 8), 1, 5) as [time] from #tt    


drop table #t
drop table #tt

------解决方案--------------------
SQL code
--测试数据:@T
declare @T table(id varchar(2),Temp int,time datetime)
insert @T
select '01',101,'9:01' union all
select '01',99,'9:03' union all
select '01',98,'9:04' union all
select '01',95,'9:07' union all
select '01',98,'9:09' union all
select '01',87,'9:11' union all
select '01',88,'9:21' union all
select '01',102,'9:23'

--先把符合条件的区间找出来,同一个id可能存在多个符合条件的区间:
select * from @T a join @T b on a.id=b.id and datediff(minute,a.time,b.time)>=20
    where a.Temp>=100 and b.Temp>=100
        and (select count(*) from @T where id=a.id and time>a.time and time<b.time)>5

select distinct a.id from @T a join @T b on a.id=b.id and datediff(minute,a.time,b.time)>=20
    where a.Temp>=100 and b.Temp>=100
        and (select count(*) from @T where id=a.id and time>a.time and time<b.time)>5
/*
id
01
*/