SQL查询的问题

SQL查询的问题,sql,sql-server-express,Sql,Sql Server Express,我需要有关sql表的帮助 该表包含以下列: EventID、PersonID、EventType、EventTimedatetime和其他一些不太重要的列 假设两种主要事件类型是开门和关门 我需要同一个人开门和关门之间的持续时间,或者他开门和开门之间的持续时间,单位为秒。这当然允许简单开门的顺序 为了弄清楚,如果人员1打开了一扇门,人员2关闭了一扇门,则不应从查询中返回任何行 我希望它是有效的,但这不是必须的 我正在使用2008 SQL microsoft serverSQLEXPRESS 以下

我需要有关sql表的帮助

该表包含以下列:

EventID、PersonID、EventType、EventTimedatetime和其他一些不太重要的列

假设两种主要事件类型是开门和关门

我需要同一个人开门和关门之间的持续时间,或者他开门和开门之间的持续时间,单位为秒。这当然允许简单开门的顺序

为了弄清楚,如果人员1打开了一扇门,人员2关闭了一扇门,则不应从查询中返回任何行

我希望它是有效的,但这不是必须的

我正在使用2008 SQL microsoft serverSQLEXPRESS

以下是一个表格示例:

EventID | PersonID | EventType | EventDate                | PreviousDoor | CurrentDoor
   1    |    1     |    1      | 12/10/2010 12:00:01.024  |      0       |     23
   2    |    1     |    2      | 12/10/2010 12:05:40.758  |      23      |     0
   3    |    2     |    1      | 12/10/2010 12:12:05.347  |      0       |     12
   4    |    1     |    1      | 12/10/2010 12:50:12.142  |      0       |     23
   5    |    2     |    2      | 12/10/2010 13:00:06.468  |      12      |     23
   6    |    3     |    1      | 13/10/2010 13:00:06.468  |      0       |     23
事件类型:1开门,2关门

结果应该是:

EventID | PersonID | EventType | EventDate                | SecondsDifference
   1    |    1     |    1      | 12/10/2010 12:00:01.024  | 339
   3    |    2     |    1      | 12/10/2010 12:12:05.347  | 2881
我真的需要你们的帮助


提前谢谢。

我想这应该可以:

    SELECT          p1.EventID,
                    p1.PersonID,
                    p1.EventType,
                    p1.EventDate,
                    DATEDIFF(SECOND, p1.EventDate, p2.EventDate) AS SecondsDifference
    FROM            [Event] p1
    LEFT JOIN       [Event] p2  --Left join to self returning only closed door events
    ON              p2.PersonID = p1.PersonID
    AND             p2.EventType = 2 -- Closed Door
    AND             p1.EventID < p2.EventID --We don't want to bring back events that happened before the next event
    WHERE           p2.EventID IS NOT NULL --We don't want to show any people that have not closed a door

我认为这应该做到:

    SELECT          p1.EventID,
                    p1.PersonID,
                    p1.EventType,
                    p1.EventDate,
                    DATEDIFF(SECOND, p1.EventDate, p2.EventDate) AS SecondsDifference
    FROM            [Event] p1
    LEFT JOIN       [Event] p2  --Left join to self returning only closed door events
    ON              p2.PersonID = p1.PersonID
    AND             p2.EventType = 2 -- Closed Door
    AND             p1.EventID < p2.EventID --We don't want to bring back events that happened before the next event
    WHERE           p2.EventID IS NOT NULL --We don't want to show any people that have not closed a door

试着这样做:

select t1.EventID, t1.PersonID, t1.EventType, t1.EventDate, datediff(second, t1.EventDate, t2.EventDate) as 'SecondsDifference'
from [Event] t1
inner join [Event] t2 on t2.PersonID = t1.PersonID and t2.EventType = 2 and t2.PreviousDoor = t2.CurrentDoor and t2.EventID < t1.EventID
where t1.EventType = 1

试着这样做:

select t1.EventID, t1.PersonID, t1.EventType, t1.EventDate, datediff(second, t1.EventDate, t2.EventDate) as 'SecondsDifference'
from [Event] t1
inner join [Event] t2 on t2.PersonID = t1.PersonID and t2.EventType = 2 and t2.PreviousDoor = t2.CurrentDoor and t2.EventID < t1.EventID
where t1.EventType = 1
使用行号和分区会有帮助吗? 我不确定下面是否是合法的SQL语句,所以请将其视为半伪代码。
SELECT *, 
  ROW_NUMBER() OVER(PARTITION BY PersonID ORDER BY EventTime) AS RowNumber,
  datediff(seconds, t2.EventTime, t1.EventTime) AS SecondsDiff
FROM Events t1 
  INNER JOIN 
    SELECT *,
      ROW_NUMBER() OVER(PARTITION BY PersonID ORDER BY EventTime) AS RowNumber 
    From Events t2 
  ON t1.RowNumber + 1 = t2.RowNumber 
    AND t1.PersonID = t2.PersonID AND t1.EventType = 1 
    AND (t2.EventType = 1 OR t2.EventType = 2)
使用行号和分区会有帮助吗? 我不确定下面是否是合法的SQL语句,所以请将其视为半伪代码。
SELECT *, 
  ROW_NUMBER() OVER(PARTITION BY PersonID ORDER BY EventTime) AS RowNumber,
  datediff(seconds, t2.EventTime, t1.EventTime) AS SecondsDiff
FROM Events t1 
  INNER JOIN 
    SELECT *,
      ROW_NUMBER() OVER(PARTITION BY PersonID ORDER BY EventTime) AS RowNumber 
    From Events t2 
  ON t1.RowNumber + 1 = t2.RowNumber 
    AND t1.PersonID = t2.PersonID AND t1.EventType = 1 
    AND (t2.EventType = 1 OR t2.EventType = 2)

我建议将左连接转换为内部连接,使p2.EventID不为空冗余-OP只需要成对的打开/关闭事件-并添加WHERE p1.EventType=1条件。@KevRitchie为什么左连接?和您需要使用CurrentDoor和PreviousDoor以获得更好的结果:@MarkBannister!正如我所做的:很好的建议。我想我太习惯于输入LEFT-JOIN:S了。不过谢谢你的建议。GMTA-不幸的是,对我来说不是周五-我建议将左连接转换为内部连接,使p2.EventID不为空冗余-OP只需要成对的打开/关闭事件-并添加WHERE p1.EventType=1条件。@KevRitchie为什么左连接?和您需要使用CurrentDoor和PreviousDoor以获得更好的结果:@MarkBannister!正如我所做的:很好的建议。我想我太习惯于输入LEFT-JOIN:S了。不过谢谢你的建议。GMTA-不幸的是,对我来说不是周五-我不确定查询是否提供了正确的结果,请注意,两个开门事件可能会配对在一起。另外,如果我打开然后关闭门1,然后再打开并关闭它4个事件,那么第一个事件不也会与最后一个事件配对吗?我可能错了,对sqlI有点生疏。我不确定查询是否提供了正确的结果,请注意,两个打开的门事件可能会配对在一起。另外,如果我打开然后关闭门1,然后再打开并关闭它4个事件,那么第一个事件不也会与最后一个事件配对吗?我可能错了,对sql有点生疏