1

パイプラインの特定のコンポーネント内のアイテムの数を取得しようとしています。パイプライン内を移動するたびに、この特定のテーブルにエントリが作成されます。

次のように保存されます。

ID:int-pk、ObjectId:varchar(25)、EventType:int、時刻:DateTime

たとえば。私が見ている時間 = 10:00

したがって、オブジェクト 1 にイベント A が午前 9 時にあり、イベント 2 が午前 10 時にある場合、ObjectId (1) を取得したいと思います。

特徴

  • ObjectId は、パイプラインを通過する項目の一意の ID であるため、実際にはそれらの項目はほとんどありません (1 つのエントリまたは各パイプライン コンポーネントで、約 10 あります)。
  • 1 日あたり最大 10,000 件の挿入が予想されます
  • パフォーマンスは少し必要です (したがって、EXISTS(...) はオプションではない可能性があります)。
  • ハードウェアは堅牢で、データセンターの SQL マシンですが、他の多くのチーム/プロセスと共有されています。

私が抱えていた問題/私が試していること:

  • 現時点での設計なので、実際のデータはありません。テストするために、概念実証のデータベースをすぐに作成する必要があります
  • ここに私が試してみようと思っていたことの少しがあります:

select  objectid, time, eventtype
from        objects
where       -- can't use time < @t because I won't get the later events
group by    objectid
having      -- 

また

select        objectid as oid, time, eventtype
from          objects
where     eventtype = 1
and       time < @t
and       exists (select  objectid, eventtype, time
              where   objectid = oid -- not sure if this is legal
              and     eventtype = 2
              and     time > @t)

お気づきかもしれませんが、私はあまり SQL を書いていないので、少し忘れてしまいました。

ID  objectid    eventtype   time
1   12345   1   09:00 AM
2   12345   2   10:00 AM


eventtypeid     description 
1           "enter house"
2           "leave house"
3           "enter work"

つまり、被験者 4 人は午前 9 時に家に入り、午前 11 時に家を出ました。12345 はサブジェクトの「名前/番号」です。

この例では、件名が午前 10 時に家にいたかどうかを確認するクエリを実行しようとしています。被験者が家に入ったが、出たことはなかった可能性は十分にあり、このクエリにはそれらが必要ありません.

質問

  • 私は正しい軌道に乗っていますか?
  • 2 番目のクエリの期待されるパフォーマンスを見積もるにはどうすればよいでしょうか (それが機能すると仮定して)。
  • ポインタ?提案?例?

すべてが高く評価されています。

4

3 に答える 3

1

特定の主題と特定の時間について、次のことができます。

select top 1 o.*
from objects o
where eventtime < @t and
      objectid = @objectid
order by eventtime desc;

Windows 関数を使用すると、これを複数のオブジェクトに拡張するのが最も簡単です。

select o.*
from (select o.*,
             row_number() over (partition by objectid order by eventtime desc) as seqnum
      from objects o
      where eventtime < @t
     ) o
where seqnum = 1;

これらはどちらも、特定の時間の前 (厳密には前) の最後のイベントに関する情報を提供します。

于 2013-05-24T21:29:40.867 に答える
0

正確に何を求めているかを理解するのは難しいですが、後の行が存在する行を返すには、単純に、SQL2012 では LEAD 関数を使用して実行できます。

DROP TABLE #test
CREATE TABLE #test (VALUE CHAR(25)) 
INSERT INTO #test VALUES('abcde'),('asaf'),('dogs'),(NULL),('')

SELECT Value, LEAD(Value,1,'Last Record') OVER (ORDER BY Value)
FROM #test

SELECT *
FROM (SELECT Value, LEAD(Value,1,'Last Record') OVER (ORDER BY Value)'Last_Flag'
       FROM #test
      )sub
WHERE Last_Flag <> 'Last Record'

上記で作成されたテスト テーブルから、次のクエリは次の行から値を取得し (2 番目のパラメーター '1' は、オフセット、何行先を検索するかを定義します)、'Last Record' が次の行としてシードされます。次の行がない場合のデフォルト値 (NULL デフォルトでは、データに NULLS がない限り問題ありません。念のため値をシードするのが好きです)。次に、最後のものは、後に行がないものを除くすべてを選択します。

各 objectID について知りたい場合は、PARTITION BY ステートメントを追加できます。IE:

LEAD(Value,1,'Last Record') OVER (PARTITION BY objectID ORDER BY Value)
于 2013-05-24T17:46:57.033 に答える