2013-02-25 2 views
1

Мне нужно выполнить скрипт запроса, чтобы отбросить журналы доступа, которые не превышают предопределенный запас (например, 2 секунды). То есть, если каждая запись была сделана пользователем с определенной датой/временем, я не хочу получать тех, у кого его дата/время не превышает диапазон по сравнению с датой/временем предыдущей записи. Я думаю, что пример более ясен.Сложный SQL QUERY с DateDIFF

Пример:

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 

Спасибо заранее!

ответ

0

Вы рассматривали решение задачи в обратном направлении?

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

Вы также можете сохранить эти журналы в отдельной таблице с помощью INSERT -Trigger (я считаю, что это данные поступают из-контроля доступа и, следовательно, вы не разрешается удалять эти записи, вы?)

Тем не менее, если вы предпочитаете, чтобы достичь того, через запрос после этого, попробовать что-то вроде:

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, который добавит еще одну группу данных, которая должна быть отклонена после предыдущего интервала действительных и недопустимых данных.

Я бы предпочел первый вариант. Зачем хранить данные и обрабатывать их потом, если вы сможете получить то, что хотите гораздо раньше и проще ?!