web-dev-qa-db-ja.com

時間枠内のサンプリングポイントのデータを取得するための最良の方法は何ですか

ある期間内のサンプリングポイントの集計値をチェックする一連のクエリを設定する方法について、いくつかのアドバイスを探しています。これはIQサーバーで実行する必要があるため、これほど多くのプロシージャコールはクールではないかもしれません;)

ウィンドウ機能を調べました。サンプリングポイントではなく、時間枠の集計データに対してのみ機能する可能性があると思います。したがって、このシナリオがある:

開始日と終了日が記載されたアイテムのリストがあります。現在アクティブなプロセスの合計を収集する必要があります。それはシステムプロセスではなく、特定の時間に何人の職人が働いていたかのようなものです。

このようなテーブルを想像してみてください(退屈な部分を省くために例を少し変更しました....完全に実行されない可能性があります)

create table items (
    id int ot null default autoincrement,
    "Type" integer,
    TimeStampStart datetime null, 
    TimeStampend datetime null
)

現在、このクエリセットで使用されています。

create table #Processes(
  "Type" integer,
  "timestamp" "datetime" null,
  "Sum" integer null
  )

set @date = '20120303'
while @date <= '20130505'
  begin
    insert into #Processes
      select "Type",'timestamp'=@date,'Sum'="count"()
        from "items"
        and "TimeStampStart" between "dateadd"("day",-"abs"(100),@date) and @date
        and "TimeStampStart" <= @date
        and "isnull"("TimeStampEnd",@date) >= @date
        group by "Type"
    set @date = "dateadd"("ss",3600,@date)
  end
select * from #Processes;

これは最善の方法ではないかもしれません。だから私はより良いアプローチを探しています;)

3
frlan

Micheael Greenの回答をさらに一歩進めて、Numbersテーブルを生成することをお勧めします。それは他の多くのアルゴリズムにも役立ちます。もう1つの便利なテーブルは、+ /-20年間のすべての日付のカレンダーテーブルです。このようなテーブルのID列からも番号を取得できます。

これが私が思いついたクエリです。簡単にSP to TVFにラップできます。これで動作します。開発データベースでテストしたので、テーブル名の前にtmpを付ける必要がありました。

>、> =、<、<=で遊んで、境界で開始/終了するプロセスをカウントするかどうかを歌います。

---- Create temp tables to test
create table tmp_numbers  (
id int null
)
insert into tmp_numbers values (0)
go
insert into tmp_numbers 
select MAX(ID)+1 from tmp_numbers 
go 1000
create clustered index Idx_ID on tmp_numbers (id)
go

create table tmp_items (
    "Type" integer,
    TimeStampStart datetime null, 
    TimeStampend datetime null
)
go

insert into tmp_items
select 1,'2012-03-03 02:13:01.000','2012-03-03 15:09:05.000'
UNION ALL
select 2,'2012-03-03 07:33:59.990','2012-03-03 14:59:10.000'
UNION ALL
select 3,'2012-03-03 22:13:01.000','2012-03-04 15:09:05.000'
UNION ALL
select 4,'2012-03-04 10:33:59.990','2012-03-04 14:59:10.000'
UNION ALL
select 5,'2012-03-04 23:20:00.000','2012-03-05 02:50:00.000'
UNION ALL
select 6,'2012-03-05 12:00:00.000','2012-03-05 23:01:00.000'

------ The query itself

declare @start datetime, @end datetime
set @start = '20120303'
set @end  = '20120305'

select 
ID,
DATEADD(hour, id, @start),
DATEADD(hour, id+1, @start),
(select COUNT (*) 
    from tmp_items 
    where TimeStampStart <= DATEADD(hour, tmp_numbers.id +1, @start) 
    and TimeStampEnd > DATEADD(hour, tmp_numbers.id, @start)

    -- To limit number of Log ("items") rows scanned:
    and TimeStampEnd >= @start

)
from tmp_numbers 
where id < DATEDIFF (hh,@start, @end)+24;

このクエリを整理して単一のCPUの制限を克服する別の方法

declare @start datetime, @end datetime
    set @start = '20120303'
    set @end  = '20120305'

create table #Temp (
StartTime datetime null,
EndTime datetime null,
RowNum int null)

insert into #Temp
  select 
    DATEADD(hour, id, @start),
    DATEADD(hour, id+1, @start),
  from tmp_numbers 
    where id < DATEDIFF (hh,@start, @end)+24;

 update #Temp
 set RowNum =  (select COUNT (*) 
        from tmp_items 
        where TimeStampStart <= #Temp.EndTime 
        and TimeStampEnd > #Temp.StartTime 

        -- To limit number of Log ("items") rows scanned:
        and TimeStampEnd >= @start  
    )
4
Stoleg

フライアン、

私は先週、このアルゴリズムについて同僚と話し合いました。まだテストする機会はありませんが、自信はあります。

1)開始時間と終了時間を時間数に変換します。これは、HOURS()関数またはDATEDIFFにすることができます。ベースラインは何でもかまいませんが、MIN(TimeStampStart)が最も便利です。 TimeStampStartを切り上げてTimeStampEndを切り下げます。結果の列をHoursStartおよびHoursEndと呼びましょう。

2) 整数テーブル _where Integer.Number >= HoursStart and Integer.Number <= HoursEnd_に参加します。これから、Integer.Numberを「HourSampled」と呼びましょう。整数テーブルは、上記の時間に変換するために選択したベースラインに応じて大きくなったり小さくなったりします。定数値1を使用してnnn(または選択したその他のもの)という新しい列を作成します。

3)nnnを列Sumに合計するType&HourSampledでグループ化します。 HourSampledは、必要に応じてDateTimeSampledに戻すことができます。

これは別々のステップでレイアウトしましたが、1つのステートメントでコーディングできます。これは、ループアルゴリズムよりも高速になります。

サンプリング頻度を変更するには、TimeStampStartを整数に変換する関数と対応する整数テーブルの内容を変更します。たとえば、15分はMINUTES(TimeStampStart)/15になります。

申し訳ありませんが、Sybaseの知識は最小限です。可能な限り正しい構文を参照しようとしました。

追加の娯楽のためにあなたは選択することができます

_select
    Type,
    REPLICATE(Sum)
from #Process
order by
    Type,
    HourSampled
_

既製のASCII棒グラフを取得するには!

3
Michael Green