2

複数の状況で機能する可能性のあるクエリを見つけようとしています。一言で言えば、データは2つの状況のいずれかになります。特定の時間枠内に発生したイベントのrecord_idを探しているとしましょう:2012年6月26日10:00AMおよび2012年6月27日11:00AMレコードはデータベースで次のようになります。

Record    Event     Time
1         Start     6/26/2012 10:05AM
1         End       6/26/2012 10:45AM
2         Start     6/26/2012 09:55AM
2         End       6/26/2012 11:05AM

レコード1の取得は、between関数を使用するだけで簡単ですが、レコード1と2の両方を返すクエリを見つけようとしています。

提案?

4

4 に答える 4

2

範囲を広げることもできますが、意図したものとは異なるレコードが返される可能性があります。

SELECT  RECORD, EVENT, TIME 
FROM SO_RecordEvent AS R
WHERE TIme BETWEEN  '6/26/2012 9:55AM'  AND '6/26/2012 11:06AM'

これにより、範囲内の開始時刻または終了時刻のいずれかを持つすべてのレコードが返されます。これには、範囲外の関連レコードも含まれます(つまり、範囲内に1回しか含まれていないが、その前または後に開始されたレコード)それ以外の開始時刻または終了時刻が表示されます)、範囲を短くすることができます。

 ;WITH X AS 
 (
    SELECT RECORD,EVENT,TIME FROM SO_RecordEvent 
 )
 SELECT R.RECORD,R.EVENT,R.TIME 
 FROM SO_RecordEvent AS R
 INNER JOIN X ON R.Record = X.Record
 WHERE X.TIme BETWEEN  '6/26/2012 10:05AM'  AND '6/26/2012 11:05AM'
 GROUP BY R.RECORD,R.EVENT,R.TIME

しかし、レコード2の例のように、範囲外で開始および終了した場合でも、その間に開始されたすべてのものを本当に提供する、このようなものが本当に必要になると思います。

編集

変更されたロジック-状況に対処する代わりに、このように考えることにしました-開始と終了内で開始したもの、開始と終了内で終了したもの、および前後に開始したもの。これは、この期間中に実行されるすべてのものをカバーすると思います(内で終了する前に開始し、内で開始および終了し、内で開始および後に終了し、前に開始し、後に終了します)

  SELECT X.RECORD,X.TIME AS STARTTIME,Y.TIME AS ENDTIME 
  FROM SO_RecordEvent AS X
  INNER JOIN SO_RecordEvent Y ON Y.Record = X.Record AND Y.EVENT = 'END'
  WHERE  X.EVENT = 'START'
  AND 
  ((X.TIME >= '6/26/2012 10:00AM' AND X.TIME <= '6/26/2012 11:00AM')
  OR (Y.TIME >= '6/26/2012 10:00AM' AND Y.TIME <= '6/26/2012 11:00AM')
  OR (X.TIME <= '6/26/2012 10:00AM' AND Y.TIME >= '6/26/2012 11:00AM'))

遊ぶ変数:

 DECLARE @START datetime, @END datetime
 SET @START = '6/26/2012 10:00AM'
 SET @END = '6/26/2012 11:00AM'

   SELECT X.RECORD,X.TIME AS STARTTIME,Y.TIME AS ENDTIME 
   FROM SO_RecordEvent AS X
   INNER JOIN SO_RecordEvent Y ON Y.Record = X.Record AND Y.EVENT = 'END'
   WHERE  X.EVENT = 'START'
   AND 
  ((X.TIME >= @START AND X.TIME <= @END)
  OR (Y.TIME >= @START AND Y.TIME <= @END)
  OR (X.TIME <= @START AND Y.TIME >= @END))
于 2012-06-27T17:53:34.527 に答える
0

私はおそらくテーブルをそれ自体に結合するでしょう-このようなもの:

SELECT *
FROM
    Table leftside
    JOIN Table rightside
        ON leftside.Record = rightside.Record
WHERE
    leftside.Event = 'Start'
    and rightside.Event = 'End'
    and [whatever time you want] >= leftside.Time
    and [whatever time you want] <= rightside.Time

編集:デモンストレーションの例

create table thingy (
    record int,
    event varchar(10),
    time datetime )

insert thingy (record,event,time) values (1,'Start','6/26/2012 10:05AM')
insert thingy (record,event,time) values (1,'End','6/26/2012 10:45AM ')
insert thingy (record,event,time) values (2,'Start','6/26/2012 09:55AM')
insert thingy (record,event,time) values (2,'End','6/26/2012 11:05AM')

DECLARE @mytime datetime
SET @mytime = '6/26/2012 9:58AM'

SELECT * 
FROM 
        thingy leftside 
    JOIN thingy rightside 
        ON leftside.Record = rightside.Record 
WHERE 
    leftside.Event = 'Start' 
    and rightside.Event = 'End' 
    and @mytime >= leftside.Time 
    and @mytime <= rightside.Time 

SET @mytime = '6/26/2012 10:10AM'
SELECT * 
FROM 
    thingy leftside 
    JOIN thingy rightside 
        ON leftside.Record = rightside.Record 
WHERE 
    leftside.Event = 'Start' 
    and rightside.Event = 'End' 
    and @mytime >= leftside.Time 
    and @mytime <= rightside.Time 

私が期待するものを与えるようです-最初のクエリに1行、2番目のクエリに2行。

于 2012-06-27T17:38:34.493 に答える
0

指定された範囲内にあるすべてのイベントのレコード番号を取得します。

SELECT Record
FROM atable
WHERE Time BETWEEN @StartTime AND @EndTime

ここで、レコード番号が上記のクエリの結果セットの行と一致するすべての行を取得します。つまり、次のようになります。

SELECT *
FROM atable
WHERE Record IN (
  SELECT Record
  FROM atable
  WHERE Time BETWEEN @StartTime AND @EndTime
)
于 2012-06-27T20:45:20.427 に答える
0

これを行う最も簡単な方法は、次を使用することです。

WITH recs AS (
SELECT Record, MIN(tme) AS startTime, MAX(tme) AS endTime
FROM records
GROUP BY Record
)
SELECT * FROM
records
WHERE startTime >= @eventsAfter
AND endTime <= @eventsBefore

(これは、少なくとも私があなたの質問を解釈した方法です)

于 2012-06-27T20:58:49.927 に答える