выберите запись после интервала не менее 1 минуты - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть приложение, которое регистрирует данные примерно через 1 секунду, если пакет исправен, что означает, что регистрация не гарантируется.Теперь клиент хочет видеть данные журнала только с промежутком не менее 1 минуты.Например, это пример схемы и данных

declare @mytable as table(ID int, tm DATETIME, Val int)

insert into @mytable values
(1,     convert(DATETIME, N'2018-12-24 17:45:25.000', 21), 1),
(2,     convert(DATETIME, N'2018-12-24 17:45:35.000', 21), 2),
(3,     convert(DATETIME, N'2018-12-24 17:45:55.000', 21), 1),
(4,     convert(DATETIME, N'2018-12-24 17:46:05.000', 21), 5),
(5,     convert(DATETIME, N'2018-12-24 17:47:25.000', 21), 2),
(6,     convert(DATETIME, N'2018-12-24 17:47:55.000', 21), 7),
(7,     convert(DATETIME, N'2018-12-24 17:48:25.000', 21), 9),
(8,     convert(DATETIME, N'2018-12-24 17:48:50.000', 21), 1),
(9,     convert(DATETIME, N'2018-12-24 17:49:25.000', 21), 1),
(10,    convert(DATETIME, N'2018-12-24 17:50:05.000', 21), 5),
(11,    convert(DATETIME, N'2018-12-24 17:50:50.000', 21), 4),
(12,    convert(DATETIME, N'2018-12-24 17:51:25.000', 21), 8),
(13,    convert(DATETIME, N'2018-12-24 17:55:25.000', 21), 4),
(14,    convert(DATETIME, N'2018-12-24 17:56:58.000', 21), 4),
(15,    convert(DATETIME, N'2018-12-24 17:58:15.000', 21), 5),
(16,    convert(DATETIME, N'2018-12-24 18:10:25.000', 21), 8);

Выходные данные должны быть

1,     convert(DATETIME, N'2018-12-24 17:45:25.000', 21), 1
5,     convert(DATETIME, N'2018-12-24 17:47:25.000', 21), 2
7,     convert(DATETIME, N'2018-12-24 17:48:25.000', 21), 9
9,     convert(DATETIME, N'2018-12-24 17:49:25.000', 21), 1
11,    convert(DATETIME, N'2018-12-24 17:50:50.000', 21), 4
13,    convert(DATETIME, N'2018-12-24 17:55:25.000', 21), 4
14,    convert(DATETIME, N'2018-12-24 17:56:58.000', 21), 4
15,    convert(DATETIME, N'2018-12-24 17:58:15.000', 21), 5
16,    convert(DATETIME, N'2018-12-24 18:10:25.000', 21), 8

Здесь, после квалифицированной записи, следующая запись для квалификации должна иметь интервал не менее 1 минуты.,Тем не менее, я должен регистрировать все исправные записи, как в какой-то другой процедуре, мне придется возвращать все записи.Таким образом, пропуск во время регистрации не вариант.Кроме того, я знаю, что могу добиться этого, используя cursor, но учитывая объем данных, это неприемлемое решение.

1 Ответ

0 голосов
/ 25 декабря 2018

Использование рекурсивного общего табличного выражения:

;WITH CTE (Id, tm, val)
AS
(
    SELECT TOP 1 *
    FROM @mytable m
    WHERE m.ID = 1

    UNION ALL

    SELECT
        p.Id,
        p.tm,
        p.val
    FROM
    (
        SELECT
            m.*, 
            ROW_NUMBER() OVER(ORDER BY c.Id) AS row_num
        FROM CTE c
        INNER JOIN @mytable m ON c.Id < m.ID AND DATEADD(MINUTE, 1, c.tm) <= m.tm
    ) AS p
    WHERE p.row_num = 1

)
SELECT *
FROM CTE c

Id          tm                      val
----------- ----------------------- -----------
1           2018-12-24 17:45:25.000 1
5           2018-12-24 17:47:25.000 2
7           2018-12-24 17:48:25.000 9
9           2018-12-24 17:49:25.000 1
11          2018-12-24 17:50:50.000 4
13          2018-12-24 17:55:25.000 4
14          2018-12-24 17:56:58.000 4
15          2018-12-24 17:58:15.000 5
16          2018-12-24 18:10:25.000 8

Но я не уверен, что это решение будет работать на больших таблицах с большим количеством записей.Возможно, вам нужна какая-то постобработка после вставки в таблицу журнала.

...