Вот мой удар в этом.У меня нет живого Oracle, и SQLFiddle не работает, поэтому, пожалуйста, сообщите, как это получается:
CREATE TABLE t (
u VARCHAR(5),
t DATETIME
);
INSERT INTO t
(u, t)
VALUES
('User1', '2001-01-01 08:15:50'),
('User1', '2001-01-01 10:42:22'),
('User1', '2001-01-01 10:42:24'),
('User1', '2001-01-01 10:42:35'),
('User1', '2001-01-01 10:50:01'),
('User2', '2001-01-01 13:23:05'),
('User2', '2001-01-01 13:23:34'),
('User2', '2001-01-01 13:24:01'),
('User2', '2001-01-01 13:24:02');
SELECT
z.u,
min(z.t) evt_start,
max(z.t) evt_end
FROM
(
SELECT y.*, SUM(prev_or_2prev_not_within) OVER(PARTITION BY u ORDER BY t ROWS UNBOUNDED PRECEDING) as ctr
FROM
(
SELECT
t.*,
CASE WHEN
t - LAG(t) OVER(PARTITION BY u ORDER BY t) < 1.0/1440.0 OR
t - LAG(t, 2) OVER(PARTITION BY u ORDER BY t) < 1.0/1440.0
THEN 0 ELSE 1
END as prev_or_2prev_not_within
FROM
t
) y
) z
GROUP BY
z.u,
z.ctr
HAVING COUNT(*) = 3
Я полагаю, что он установит инкрементный счетчик, который не увеличивается, когда предыдущий или предыдущий предыдущийряд находится в пределах минуты текущего ряда.Он делает это, классифицируя строки как 0 или 1, и когда 0 происходит, операция sum-all-previousing-rows генерирует счетчик, который не изменяется.Затем он группирует на этом счетчике ровно 3 вхождения.Раздел заставляет счетчик работать на пользователя
Вы можете увидеть его в действии здесь: https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=018125210ecd071f3d11e3d4b3d3e670
Это SQL Server (как уже отмечалось, у меня нет оракула), но термины, используемые для sqlserver и логики, должны быть в целом схожи для оракула - оракул поддерживает запаздывание, неограниченные суммы, наличие и т. д., и он вычисляет дату в терминах dateA - dateB ->число с плавающей запятой, представляющее целое или части дня (и 1440 минут в день, 1/1440 должно представлять собой плавание в одну минуту).Типы данных, которые использует sqlserver, могут немного отличаться от oracle, и этот запрос зависит от того, как столбец TIME (я назвал его t
- не нравиться имена столбцов, которые являются зарезервированными словами / ключевыми словами) - это дата, а не строка, которая выглядит как время.Если ваши данные представляют собой строку, рассортируйте ее так, чтобы ее не было (используйте внутренний подзапрос для создания даты и времени или измените свое хранилище данных так, чтобы оно сохранялось как тип даты и времени)
Вы сказали, что хотите получить результатон сообщает пользователю и время события - самый простой способ сделать это - использовать min и max, чтобы получить диапазон дат.Если вы отчаянно хотите показать все 3 строки, вы можете присоединить выходные данные этого запроса к таблице с датой между evt_start и evt_end, или вы можете использовать какую-то функцию типа string_aggregate, чтобы получить список раз подряд.вне внешней групповой операции