2

どうやって始めればいいのかわからない質問があります。誰かが私を助けてくれることを願っています。まずは表の説明から

Device_Id、Device_Status、Begin_dt、End_dt の 4 つの列を持つデバイス テーブルがあります。6 つの異なるステータスがあり、3 (簡単にするためにステータス 1、4、5 としましょう) はデバイスが「オンライン」であることを意味します。

このテーブルの例は次のとおりです。

Id | Status| Begin                   |  End
001|     1 | 2012-09-01 00:00:00.000 | 2012-09-01 01:00:00.000
001|     2 | 2012-09-01 01:00:00.000 | 2012-09-01 01:35:00.000
001|     1 | 2012-09-01 01:35:00.000 | 2012-09-01 02:05:00.000
003|     1 | 2012-09-01 05:00:00.000 | 2012-09-01 07:02:00.000
004|     1 | 2012-09-01 01:00:00.000 | 2012-09-01 01:35:00.000
003|     2 | 2012-09-01 07:02:00.000 | NULL

私のクエリは、すべてのデバイスが 24 時間ごとに「オンライン」を示すステータスになっている TIME の合計を返す必要があります。

だから私のリターンは次のようになります

Hour| Online_Time
0   | 5:30:12.11
1   | 3:30:12.11
2   | 4:30:12.11
3   | 5:30:12.11
4   | 6:30:12.11
5   | 4:00:00.00
6   | 1:30:12.11
7   | 3:30:12.11
8   | 4:30:12.11
etc |

したがって、1 日の 1 時間ごとに、(明らかに) 1 時間以上のオンライン時間を持つことができます。

これはちょっと複雑で、うまく説明できたことを願っています。助けたり、提案をしたりできる人なら誰でも大歓迎です。

-J


with const as (
    select dateadd(hour, 1, cast(cast(getdate() -1 as date) as datetime)) as midnnight
    ),
allhours as (
    select 0 as hour, midnight as timestart, dateadd(hour, 1, timestart) as timeend from const union all
    select 1 as hour, dateadd(hour, 1, midnight), dateadd(hour, 2, midnight) from const union all
    select 2 as hour, dateadd(hour, 2, midnight), dateadd(hour, 3, midnight) from const union all
    select 3 as hour, dateadd(hour, 3, midnight), dateadd(hour, 4, midnight) from const union all
    select 4 as hour, dateadd(hour, 4, midnight), dateadd(hour, 5, midnight) from const union all
    select 5 as hour, dateadd(hour, 5, midnight), dateadd(hour, 6, midnight) from const union all
    select 6 as hour, dateadd(hour, 6, midnight), dateadd(hour, 7, midnight) from const union all
    select 7 as hour, dateadd(hour, 7, midnight), dateadd(hour, 8, midnight) from const union all
    select 8 as hour, dateadd(hour, 8, midnight), dateadd(hour, 9, midnight) from const union all
    select 9 as hour, dateadd(hour, 9, midnight), dateadd(hour, 10, midnight) from const union all
    select 10 as hour, dateadd(hour, 10, midnight), dateadd(hour, 11, midnight) from const union all
    select 11 as hour, dateadd(hour, 11, midnight), dateadd(hour, 12, midnight) from const union all
    select 12 as hour, dateadd(hour, 12, midnight), dateadd(hour, 13, midnight) from const union all
    select 13 as hour, dateadd(hour, 13, midnight), dateadd(hour, 14, midnight) from const union all
    select 14 as hour, dateadd(hour, 14, midnight), dateadd(hour, 15, midnight) from const union all
    select 15 as hour, dateadd(hour, 15, midnight), dateadd(hour, 16, midnight) from const union all
    select 16 as hour, dateadd(hour, 16, midnight), dateadd(hour, 17, midnight) from const union all
    select 17 as hour, dateadd(hour, 17, midnight), dateadd(hour, 18, midnight) from const union all
    select 18 as hour, dateadd(hour, 18, midnight), dateadd(hour, 19, midnight) from const union all
    select 19 as hour, dateadd(hour, 19, midnight), dateadd(hour, 20, midnight) from const union all
    select 20 as hour, dateadd(hour, 20, midnight), dateadd(hour, 21, midnight) from const union all
    select 21 as hour, dateadd(hour, 21, midnight), dateadd(hour, 22, midnight) from const union all
    select 22 as hour, dateadd(hour, 22, midnight), dateadd(hour, 23, midnight) from const union all
    select 23 as hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight) from const union all
   ) 
select ah.hour,
   sum(datediff(ms, (case when ah.timestart >= dt.Begin_Dt then timestart else dt.Begin_Dt end),
                    (case when ah.timeend <= dt.End_Dt then ah.timeend else dt.End_Dt end))) as totalms,
   cast(dateadd(ms, sum(datediff(ms, (case when ah.timestart >= dt.Begin_Dt then timestart else dt.Begin_Dt end),
                                 (case when ah.timeend <= dt.End_Dt then ah.timeend else dt.End_Dt end))),0) as time
                                 ) as totalTime
from allhours as ah left outer join
     dataTable as dt
     on ah.timestart< coalesce(dt.End_dt, getdate()) and
        ah.timeend >= dt.Begin_Dt
group by ah.hour
order by ah.hour

これは私が今持っているものです。「)」でエラーが発生しています

select 23 as hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight) from const union all
   )  <----- Incorrect syntax near ')'. Expecting SELECT, or '('.
select ah.hour,
4

2 に答える 2

1

あなたの問題は、期間を時間単位で分割する必要があることです。したがって、1日のすべての時間から始める必要があります。次に、オーバーラップを計算し、差を合計して (ミリ秒単位で)、すべてを出力の時間に変換します。

with const as (
        select dateadd(hour, 1, cast(cast(getdate() -1 as date) as datetime)) as midnight            
    ),
    allhours as (
        select 0 as hour, midnight as timestart, dateadd(hour, 1, midnight) as timeend from const union all
        select 1 as hour, dateadd(hour, 1, midnight), dateadd(hour, 2, midnight) from const union all
        select 2 as hour, dateadd(hour, 2, midnight), dateadd(hour, 3, midnight)  from const union all
        . . .
        select 23 as hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight) from const
    )
select ah.hour,
       sum(datediff(ms, (case when ah.timestart >= dt.begin then timestart else dt.begin end),
                        (case when ah.timeend <= dt.end then ah.timeend else dt.end end)
                   ) 
           ) as totalms,
       cast(dateadd(ms, sum(datediff(ms, (case when ah.timestart >= dt.begin then timestart else dt.begin end),
                                     (case when ah.timeend <= dt.end then ah.timeend else dt.end end)
                                    )
                           ),
                     0) as time
           ) as totalTime
from allhours ah left outer join
     DeviceTable dt
     on ah.timestart< coalesce(dt.end, getdate()) and
        ah.timeend >= dt.begin
group by ah.hour
order by ah.hour

また、これを機能させるには、「begin」と「end」を二重引用符または角括弧で囲む必要があります。これらは T-SQL の予約語です。そして、「...」を置き換える必要があります。3 時間から 22 時間までの追加の回線があります。

于 2012-09-12T13:31:16.830 に答える
0

このような何かがあなたを始めるかもしれません。

select  SUM(datediff(second, Begin_dt, End_dt)) as seconds_online
        ,DATEPART(hour, Begin_dt) as [hour]
from table
where device_status in (1,4,5)
group by DATEPART(hour, Begin_dt)

結果をフォーマットするには、次の質問に従うことをお勧めします。

SQL-秒から日、時、分、秒

于 2012-09-12T13:03:23.547 に答える