基于SQL

时间:2017-06-01 19:53:14

标签: sql sql-server datetime

我在计算SQL中记录之间传递的时间时遇到了一些问题。 或者在我的情况下,该项目没有活动多长时间。

数据样本:

Item  Not_Active Active Created
A     0          1      2017-01-01 10:03:15 
A     1          0      2017-01-01 12:05:55
A     0          1      2017-01-01 13:05:55
A     1          0      2017-02-03 12:05:55
A     0          1      2017-02-05 13:05:55
B     1          0      2017-01-10 04:05:20 
B     0          1      2017-01-10 07:05:20 

因此,主要目标是对每个项目的停用和激活之间的所有时间进行总结。答案应该在几秒钟内。我应该使用什么样的查询?

挑战二:计算某些日期之间的非活动时间。例如,对于在2017-02-01和2017-02-28之间的项目A.

挑战三:计算一夜之间的活跃时间,假设从凌晨0点到凌晨5点。

我不知道我应该从哪里开始。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我创建了一个小样本如何制作它。

    create table #table (item char, not_active int, active int, created datetime)

    insert into #table values('A', 0, 1, '2017-01-01 10:03:15') 
    insert into #table values('A', 1, 0, '2017-01-01 12:05:55') 
    insert into #table values('A', 0, 1, '2017-01-01 13:05:55') 
    insert into #table values('A', 1, 0, '2017-02-03 12:05:55') 
    insert into #table values('A', 0, 1, '2017-02-05 13:05:55') 
    insert into #table values('B', 1, 0, '2017-01-10 04:05:20') 
    insert into #table values('B', 0, 1, '2017-01-10 07:05:20') 

    declare @very_hard table (item char, 
                          not_active int, 
                          active int, 
                          created datetime,
                          before datetime, 
                          afters datetime,
                          days_diff_stoped int,
                          hourstoped int )

declare very_hard_challenge cursor Local
for

select 
item,
active,
not_active,
created,
LAG(created,1,0)over(partition by item order by created) as before,
LEAD(created,1,0)over(partition by item order by created) as afters,
datediff(day,LAG(created,1,0)over(partition by item order by created),created) as days_diff_stoped
from #table
--where item = 'B'
order by created asc

declare @item char, 
        @not_active int, 
        @active int, 
        @created datetime,
        @days_diff_stoped int,
        @before datetime, 
        @afters datetime

open very_hard_challenge

fetch next from very_hard_challenge into @item, @not_active, @active, @created, @before, @afters, @days_diff_stoped

WHILE @@FETCH_STATUS=0
    begin 
        declare @datebegin datetime = @before
        declare @hourstoped int = 0
        if @datebegin != '1900-01-01 00:00:00.000'
        begin
            while @datebegin < convert(datetime,@created)
                begin 
                        if datepart(hour,@datebegin) in(0,1,2,3,4,5)
                            begin
                                set @hourstoped = @hourstoped+1
                            end 

                            set @datebegin = DATEADD(hour,1,@datebegin)
                end
        end

        insert into @very_hard values (@item, @not_active, @active, @created, @before, @afters, @days_diff_stoped, @hourstoped)

        fetch next from very_hard_challenge into @item, @not_active, @active, @created, @before, @afters, @days_diff_stoped
    end

close very_hard_challenge
deallocate very_hard_challenge

select * from @very_hard

这段代码很简单,但你可以做得更好。任何有关此代码的问题请告诉我,我会做出回答。