Doing a comparison using the previous row?

select, sql, sql-server, sql-server-2008

Solution

DECLARE
  @n             INT,
  @speed_limit   INT
SELECT
  @n             = 5,
  @speed_limit   = 10

;WITH
  partitioned AS
(
  SELECT
    *,
    CASE WHEN speed < @speed_limit THEN 1 ELSE 0 END   AS PartitionID
  FROM
    Movement
)
,
  sequenced AS
(
  SELECT
    ROW_NUMBER() OVER (                         ORDER BY EventTime) AS MasterSeqID,
    ROW_NUMBER() OVER (PARTITION BY PartitionID ORDER BY EventTime) AS PartIDSeqID,
    *
  FROM
    partitioned
)
,
  filter AS
(
  SELECT
    MasterSeqID - PartIDSeqID    AS GroupID,
    MIN(MasterSeqID)             AS GroupFirstMastSeqID,
    MAX(MasterSeqID)             AS GroupFinalMastSeqID
  FROM
    sequenced
  WHERE
    PartitionID = 1
  GROUP BY
    MasterSeqID - PartIDSeqID
  HAVING
    COUNT(*) >= @n
)
SELECT
  sequenced.*
FROM
  filter
INNER JOIN
  sequenced
    ON  sequenced.MasterSeqID >= filter.GroupFirstMastSeqID
    AND sequenced.MasterSeqID <= filter.GroupFinalMastSeqID

Alternative final steps (inspired by @t-clausen-dk), to avoid an additional `JOIN`. I would test both to see which is more performant.

,
  filter AS
(
  SELECT
    MasterSeqID - PartIDSeqID                              AS GroupID,
    COUNT(*) OVER (PARTITION BY MasterSeqID - PartIDSeqID) AS GroupSize,
    *
  FROM
    sequenced
  WHERE
    PartitionID = 1
)
SELECT
  *
FROM
  filter
WHERE
  GroupSize >= @n

Problem

I'm trying to work out an efficient way of comparing two rows in SQL Server 2008. I need to write a query which finds all rows in the `Movement` table which have `Speed < 10` N consecutive times. The structure of the table is: EventTime Speed If the data were: ``` 2012-02-05 13:56:36.980, 2 2012-02-05 13:57:36.980, 11 2012-02-05 13:57:46.980, 2 2012-02-05 13:59:36.980, 2 2012-02-05 14:06:36.980, 22 2012-02-05 15:56:36.980, 2 ``` Then it would return rows 3/4 (13:57:46.980 / 13:59:36.980) if I looked for 2 consecutive rows, and would return nothing if I looked for three consecutive rows. The order of the data is EventTime/DateTime only. Any help you could give me would be great. I'm considering using cursors but they're usually pretty inefficient. Also, this table is approximately 10m rows in size, so the more efficient the better! :) Thanks!

Original source