1

我需要编写一个查询以丢弃不超过预定余量(例如 2 秒)的访问日志。也就是说,如果每条记录是由用户在特定日期/时间制作的,我不想让那些其日期/时间不超过与上一条记录的日期/时间相比范围的人。我认为一个例子更清楚。

例子:

LogIndex, UserID, Date / Time

1. 01551, 20.02.2013 17:41:45.000
2. 01551, 20.02.2013 17:41:45.900 *
3. 01551, 20.02.2013 17:41:46.150 *
4. 01551, 20.02.2013 20:41:47.000

5. 01552, 02/20/2013 17:42:45.000
6. 01552, 20.02.2013 17:42:46.000 *
7. 01552, 02/20/2013 19:45:45.000 *

被丢弃的记录,因为它的日期/时间不超过上一条记录的 2 秒余量。在第一种情况下,应该丢弃两条记录,因为它们都没有超过这个边距。

这是创建临时表并添加先前记录以进行测试的代码:

CREATE TABLE # TEMP (LogIndex int, UserID nvarchar (10), LogTime datetime)

insert into # temp select 1, '01551 ', '20 / 02/2013 17:41:45.000'
insert into # temp select 2, '01551 ', '20 / 02/2013 17:41:45.900'
insert into # temp select 3, '01551 ', '20 / 02/2013 17:41:46.150'
insert into # temp select 4, '01551 ', '20 / 02/2013 20:41:47.000'
insert into # temp select 5, '01552 ', '20 / 02/2013 17:42:45.000'
insert into # temp select 6, '01552 ', '20 / 02/2013 17:42:46.000'
insert into # temp select 7, '01552 ', '20 / 02/2013 19:45:45.000'

select * from # temp

DROP TABLE # temp

提前致谢!

4

1 回答 1

0

您是否考虑过反过来解决任务?

您可以在存储访问日志的表上创建一个INSERT-Trigger 并拒绝与前任的时间差小于您定义的数据。获取最后保存的数据并将其与当前数据进行比较应该更容易,userID而不是在收集数据后编写一个查询来解决您的任务。

您还可以通过 -Trigger 将这些日志保存在单独的表中INSERT(我相信这些数据来自访问控制,因此您不允许删除这些记录,是吗?)

不过,如果您更喜欢事后通过查询来实现,请尝试以下操作:

WITH "CTE" AS
(
    SELECT 
        T1.* 
        , diff = DATEDIFF( MS, T2.LogTime, T1.LogTime )
    FROM 
        #TEMP AS T1
        LEFT JOIN #TEMP AS T2
            ON 1 = 1
            AND T1.LogIndex = T2.LogIndex + 1
            AND T1.UserID = T2.UserID
)
, "ROLSUM" AS
(
    SELECT
        *
        , sumDiff = ( SELECT SUM(diff) FROM "CTE" AS C2 WHERE C2.LogIndex <= C1.LogIndex AND C2.UserId = C1.UserId )
    FROM
        "CTE" AS C1
)
SELECT 
    LogIndex, UserID, LogTime
FROM 
    ROLSUM
WHERE
    sumDiff > 2000 OR sumDiff IS NULL

请注意,此查询只是一个提示。它适用于您的演示数据,但如果您添加更多数据,则会失败,userID这会添加另一组数据,这些数据应该在之前的有效和无效数据间隔之后被拒绝。

我更喜欢第一个变体。如果您能够更早、更轻松地获得想要的东西,为什么还要存储数据并在之后进行处理?!

于 2013-02-25T12:37:21.843 回答