Найдите количество записей, созданных в определенном диапазоне одним родителем - PullRequest
0 голосов
/ 19 июня 2020

Есть таблица, в которой происходит запись из различных модулей системы.

Запись выглядит так:

ModuleId  | DateTime        | OperationId
1          2020-03-15 21:00  4
1          2020-03-15 21:03  5
2          2020-03-15 21:04  2
3          2020-03-15 21:05  4
2          2020-03-15 21:07  5
3          2020-03-15 21:32  3

Как узнать количество записей, сгенерированных в интервал 15 минут на один ModuleId, но с другим OperationId?

Результат:

TotalRecords | SatisfyingEntries
6             2

Пример

1 | 21:15 | 1 this
1 | 21:17 | 3 and this is 1 interval
1 | 21:32 | 2 falls into the interval with the second record

Ответы [ 3 ]

0 голосов
/ 19 июня 2020

Всего записей - простой результат группировки, здесь никаких уловок. Для другой части вашего вопроса может работать что-то вроде следующего (не проверено на граничные условия):

select count(distinct moduleid)
from (
    select moduleid
    from log_tb t1
    where exists (
        select *
        from log_tb t2
        where t2.moduleid = t1.moduleid
            and t2.operationid <> t1.operationid
            and datediff(minute, t1.[datetime], t2.[datetime]) between 0 and 15
    )
) x
0 голосов
/ 19 июня 2020

Если ваш общий набор данных не очень велик, вы можете go с помощью простого коррелированного подзапроса.

SELECT d.ModuleID, d.OperationID, d.datm
    , ( 
        SELECT count(*) 
        FROM d d2 
        WHERE d.ModuleID = d2.ModuleID
           AND d2.datm >= d.datm 
            AND d2.datm <= DATEADD(minute, 15, d.datm)
    ) AS SatisfyingEntries
    , ( SELECT count(*) FROM d d3 ) AS TotalRecords
FROM d
ORDER BY d.ModuleID, d.datm

Но если этот набор данных больше, чем несколько тысяч строк, вы можете посмотреть в Причудливом обновлении, которое я предложил выше. Хотя делают немного разные вещи.

Обратите внимание, что этот запрос вычисляет для 15 минут ПОСЛЕ события, поэтому это не настоящее скользящее 15-минутное окно. Это совершенно другая проблема, с которой должно работать Quirky Update.

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

И последнее примечание: если TotalRecords всегда будет подсчетом всех записей, вам может быть лучше получить это в другом запросе, в зависимости от того, как вы планируете использовать эти данные.

0 голосов
/ 19 июня 2020

Я думаю, это именно то, что вы ищете:

SELECT ModuleId,COUNT(DISTINCT OperationId) AS number_of_records
FROM log_tb
WHERE DateTime >= sysdate - (15/1440)
GROUP BY ModuleId;

Вы можете удалить GROUP BY, добавив другое условие ('=' или 'in ()', но я настоятельно рекомендую использовать ' = 'если вам нужен только один ModuleId)

SELECT COUNT(DISTINCT OperationId) as number_of_records
FROM log_tb
WHERE ModuleId = : ModuleId /*ModuleId in (ModuleId1,ModuleId2,... )*/ 
      AND DateTime >= sysdate - (15/1440);

sysdate может быть другим подзапросом с MAX, поэтому вы получите время для первой записи для указанного c ModuleId

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...