尝试找出可能适用于多种情况的查询。简而言之,数据可以是两种情况之一。假设我正在寻找在给定时间范围内发生的事件的record_id:6/26/2012 10:00 AM和6/27/2012 11:00 AM记录在数据库中可能如下所示:
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的查询。
建议?
答案 0 :(得分:1)
您可以简单地扩大范围,但这可能会带回与您想要的不同的记录。
SELECT RECORD, EVENT, TIME
FROM SO_RecordEvent AS R
WHERE TIme BETWEEN '6/26/2012 9:55AM' AND '6/26/2012 11:06AM'
这将返回任何具有该范围内的开始或结束时间的记录,包括超出范围的相关记录(换句话说,记录只有一次在该范围内 - 但在之前或结束时开始之后 - 它仍将显示其外的开始或结束时间)并允许您缩短范围。
;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))
答案 1 :(得分: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 :(得分:0)
获取属于给定范围内的所有事件的记录#:
SELECT Record
FROM atable
WHERE Time BETWEEN @StartTime AND @EndTime
现在只需获取其记录#s与上述查询结果集中的记录匹配的所有行,即如下所示:
SELECT *
FROM atable
WHERE Record IN (
SELECT Record
FROM atable
WHERE Time BETWEEN @StartTime AND @EndTime
)
答案 3 :(得分: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
(这是我解释你的问题的方式,至少)