Complex SQL QUERY with DateDIFF

  • Hi all,

    I need to script a query to discard access logs that not exceeding a predetermined margin (eg. 2 seconds). That is, if each record was made by a user on a especific date / time, I don't want to get those who its date / time does not exceed the range compared with the date / time of the previous record. I think an example is clearer.

    Example:

    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

    *: Records to discard because its date / time does not exceed the margin of 2 seconds over the previous record. In the first case two records should be discarted because both not exceed this margin.

    Here's the code that creates the temporary table and adds the previous records to test:

    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

    Thanks in advance!

  • Hi and welcome to the SSC. Nice job posting ddl and sample data!!!

    I made a couple changes so that it will work for everybody. This query works for your sample data.

    if Object_id('tempdb..#TEMP') is not null

    DROP TABLE #temp

    set dateformat dmy

    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

    ;with cte as

    (

    select *, ROW_NUMBER() over(partition by UserID order by LogTime) as RowNum

    from #temp

    )

    select cte.*

    from cte

    outer apply

    (

    select top 1 cte2.*

    from cte cte2

    where cte2.UserID = cte.UserID

    and cte2.LogTime < cte.LogTime

    order by cte2.LogTime

    ) x

    where x.LogTime is null

    or datediff(second, x.LogTime, cte.LogTime) > 2

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

  • SET DATEFORMAT DMY

    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 t.*, x.*

    FROM #temp t

    OUTER APPLY (

    SELECT ti.*, calc.Diff

    FROM #temp ti

    CROSS APPLY (SELECT Diff = DATEDIFF(ss, ti.LogTime, t.LogTime)) calc

    WHERE ti.UserID = t.UserID

    AND ti.LogIndex < t.LogIndex

    AND calc.Diff BETWEEN 0 AND 2

    ) x

    ORDER BY t.LogIndex

    ----------------------------------------------------

    SELECT t.*

    FROM #temp t

    WHERE NOT EXISTS (

    SELECT 1

    FROM #temp ti

    WHERE ti.UserID = t.UserID

    AND ti.LogIndex < t.LogIndex

    AND DATEDIFF(ss, ti.LogTime, t.LogTime) BETWEEN 0 AND 2

    )

    ORDER BY t.LogIndex

    -------------------------------------------------------------

    SELECT t.*, x.*

    FROM #temp t

    OUTER APPLY (

    SELECT ti.*

    FROM #temp ti

    WHERE ti.UserID = t.UserID

    AND ti.LogIndex <> t.LogIndex

    AND t.LogTime BETWEEN ti.LogTime AND DATEADD(ss,2,ti.LogTime)

    ) x

    ORDER BY t.LogIndex

    SELECT t.*

    FROM #temp t

    WHERE NOT EXISTS (

    SELECT 1

    FROM #temp ti

    WHERE ti.UserID = t.UserID

    AND ti.LogIndex <> t.LogIndex

    AND t.LogTime BETWEEN ti.LogTime AND DATEADD(ss,2,ti.LogTime)

    )

    ORDER BY t.LogIndex

    --------------------------------------------------------------

    DROP TABLE #Temp

    “Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • Hi all, thanks for your answers,

    if i put this records into temp table these solutions doesn't works.

    insert into TEMP select 1, '01551', '20/02/2013 17:41:45.000' --ok

    insert into TEMP select 19, '01551', '20/02/2013 17:41:45.400'

    insert into TEMP select 20, '01551', '20/02/2013 17:41:45.700'

    insert into TEMP select 8, '01551', '20/02/2013 17:41:45.800'

    insert into TEMP select 2, '01551', '20/02/2013 17:41:45.900'

    insert into TEMP select 9, '01551', '20/02/2013 17:41:45.950'

    insert into TEMP select 21, '01551', '20/02/2013 17:41:46.100'

    insert into TEMP select 3, '01551', '20/02/2013 17:41:46.150'

    insert into TEMP select 22, '01551', '20/02/2013 17:41:46.990'

    insert into TEMP select 31, '01551', '20/02/2013 17:41:47.140'--ok

    insert into TEMP select 32, '01551', '20/02/2013 17:41:47.940'

    insert into TEMP select 33, '01551', '20/02/2013 17:41:48.120'

    insert into TEMP select 34, '01551', '20/02/2013 17:41:48.720'

    insert into TEMP select 10, '01551', '20/02/2013 20:41:45.600'--ok

    insert into TEMP select 11, '01551', '20/02/2013 20:41:45.900'

    insert into TEMP select 4, '01551', '20/02/2013 20:41:47.000'

    insert into TEMP select 35, '01551', '20/02/2013 20:41:47.100'

    insert into TEMP select 36, '01551', '20/02/2013 20:41:47.600'--ok

    insert into TEMP select 37, '01551', '20/02/2013 20:41:47.900'

    insert into TEMP select 24, '01551', '20/02/2013 20:41:47.700'

    insert into TEMP select 25, '01551', '20/02/2013 20:41:48.990'

    insert into TEMP select 26, '01551', '20/02/2013 20:41:49.100'

    insert into TEMP select 5, '01552', '20/02/2013 17:42:45.000'--ok

    insert into TEMP select 12, '01552', '20/02/2013 17:42:45.500'

    insert into TEMP select 6, '01552', '20/02/2013 17:42:46.000'

    insert into TEMP select 13, '01552', '20/02/2013 17:42:46.800'

    insert into TEMP select 12, '01552', '20/02/2013 17:42:45.500'

    insert into TEMP select 27, '01552', '20/02/2013 17:42:46.100'

    insert into TEMP select 28, '01552', '20/02/2013 17:42:46.600'

    insert into TEMP select 29, '01552', '20/02/2013 19:45:45.400'--ok

    insert into TEMP select 30, '01552', '20/02/2013 19:45:45.900'

    insert into TEMP select 15, '01552', '20/02/2013 19:45:46.200'

    insert into TEMP select 16, '01553', '20/02/2013 19:45:45.100'--ok

    insert into TEMP select 17, '01553', '20/02/2013 19:45:45.600'

    insert into TEMP select 18, '01553', '20/02/2013 23:45:45.000'--ok

    insert into TEMP select 19, '01553', '20/02/2013 23:45:45.200'

    the records with ok are the records to show

    thanks for advance,

  • The requirements shown by your last post are different from the requirements from your first post.

    In your first post you state you want only the records that are equal or more than 2 seconds apart.

    In your last post your criteria shows that you want records that are equal or mor than 2 seconds from the last valid record.

    Which is it?

    If you run the following code you'll find that there are only 6records that meet your initial criteria rather than the 8 you've marked.

    if Object_id('tempdb..#TEMP') is not null

    DROP TABLE #temp

    set nocount on

    set dateformat dmy

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

    insert into #temp select 1, '01551', '20/02/2013 17:41:45.000' --ok

    insert into #temp select 19, '01551', '20/02/2013 17:41:45.400'

    insert into #temp select 20, '01551', '20/02/2013 17:41:45.700'

    insert into #temp select 8, '01551', '20/02/2013 17:41:45.800'

    insert into #temp select 2, '01551', '20/02/2013 17:41:45.900'

    insert into #temp select 9, '01551', '20/02/2013 17:41:45.950'

    insert into #temp select 21, '01551', '20/02/2013 17:41:46.100'

    insert into #temp select 3, '01551', '20/02/2013 17:41:46.150'

    insert into #temp select 22, '01551', '20/02/2013 17:41:46.990'

    insert into #temp select 31, '01551', '20/02/2013 17:41:47.140'--ok

    insert into #temp select 32, '01551', '20/02/2013 17:41:47.940'

    insert into #temp select 33, '01551', '20/02/2013 17:41:48.120'

    insert into #temp select 34, '01551', '20/02/2013 17:41:48.720'

    insert into #temp select 10, '01551', '20/02/2013 20:41:45.600'--ok

    insert into #temp select 11, '01551', '20/02/2013 20:41:45.900'

    insert into #temp select 4, '01551', '20/02/2013 20:41:47.000'

    insert into #temp select 35, '01551', '20/02/2013 20:41:47.100'

    insert into #temp select 36, '01551', '20/02/2013 20:41:47.600'--ok

    insert into #temp select 37, '01551', '20/02/2013 20:41:47.900'

    insert into #temp select 24, '01551', '20/02/2013 20:41:47.700'

    insert into #temp select 25, '01551', '20/02/2013 20:41:48.990'

    insert into #temp select 26, '01551', '20/02/2013 20:41:49.100'

    insert into #temp select 5, '01552', '20/02/2013 17:42:45.000'--ok

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 6, '01552', '20/02/2013 17:42:46.000'

    insert into #temp select 13, '01552', '20/02/2013 17:42:46.800'

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 27, '01552', '20/02/2013 17:42:46.100'

    insert into #temp select 28, '01552', '20/02/2013 17:42:46.600'

    insert into #temp select 29, '01552', '20/02/2013 19:45:45.400'--ok

    insert into #temp select 30, '01552', '20/02/2013 19:45:45.900'

    insert into #temp select 15, '01552', '20/02/2013 19:45:46.200'

    insert into #temp select 16, '01553', '20/02/2013 19:45:45.100'--ok

    insert into #temp select 17, '01553', '20/02/2013 19:45:45.600'

    insert into #temp select 18, '01553', '20/02/2013 23:45:45.000'--ok

    insert into #temp select 19, '01553', '20/02/2013 23:45:45.200'

    ; with setrows

    as

    (

    select *

    , ROW_NUMBER() over (order by logtime asc) as rownum

    from #TEMP

    )

    select sr1.*, sr2.Logtime, DATEDIFF(ss,sr1.logtime,sr2.logtime) timeDifferential

    from setrows sr1

    inner join setrows sr2

    on sr1.rownum = sr2.rownum - 1

    set nocount off

    drop table #TEMP

  • Erin Ramsay (3/12/2013)


    The requirements shown by your last post are different from the requirements from your first post.

    In your first post you state you want only the records that are equal or more than 2 seconds apart.

    In your last post your criteria shows that you want records that are equal or mor than 2 seconds from the last valid record.

    Which is it?

    If you run the following code you'll find that there are only 6records that meet your initial criteria rather than the 8 you've marked.

    if Object_id('tempdb..#TEMP') is not null

    DROP TABLE #temp

    set nocount on

    set dateformat dmy

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

    insert into #temp select 1, '01551', '20/02/2013 17:41:45.000' --ok

    insert into #temp select 19, '01551', '20/02/2013 17:41:45.400'

    insert into #temp select 20, '01551', '20/02/2013 17:41:45.700'

    insert into #temp select 8, '01551', '20/02/2013 17:41:45.800'

    insert into #temp select 2, '01551', '20/02/2013 17:41:45.900'

    insert into #temp select 9, '01551', '20/02/2013 17:41:45.950'

    insert into #temp select 21, '01551', '20/02/2013 17:41:46.100'

    insert into #temp select 3, '01551', '20/02/2013 17:41:46.150'

    insert into #temp select 22, '01551', '20/02/2013 17:41:46.990'

    insert into #temp select 31, '01551', '20/02/2013 17:41:47.140'--ok

    insert into #temp select 32, '01551', '20/02/2013 17:41:47.940'

    insert into #temp select 33, '01551', '20/02/2013 17:41:48.120'

    insert into #temp select 34, '01551', '20/02/2013 17:41:48.720'

    insert into #temp select 10, '01551', '20/02/2013 20:41:45.600'--ok

    insert into #temp select 11, '01551', '20/02/2013 20:41:45.900'

    insert into #temp select 4, '01551', '20/02/2013 20:41:47.000'

    insert into #temp select 35, '01551', '20/02/2013 20:41:47.100'

    insert into #temp select 36, '01551', '20/02/2013 20:41:47.600'--ok

    insert into #temp select 37, '01551', '20/02/2013 20:41:47.900'

    insert into #temp select 24, '01551', '20/02/2013 20:41:47.700'

    insert into #temp select 25, '01551', '20/02/2013 20:41:48.990'

    insert into #temp select 26, '01551', '20/02/2013 20:41:49.100'

    insert into #temp select 5, '01552', '20/02/2013 17:42:45.000'--ok

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 6, '01552', '20/02/2013 17:42:46.000'

    insert into #temp select 13, '01552', '20/02/2013 17:42:46.800'

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 27, '01552', '20/02/2013 17:42:46.100'

    insert into #temp select 28, '01552', '20/02/2013 17:42:46.600'

    insert into #temp select 29, '01552', '20/02/2013 19:45:45.400'--ok

    insert into #temp select 30, '01552', '20/02/2013 19:45:45.900'

    insert into #temp select 15, '01552', '20/02/2013 19:45:46.200'

    insert into #temp select 16, '01553', '20/02/2013 19:45:45.100'--ok

    insert into #temp select 17, '01553', '20/02/2013 19:45:45.600'

    insert into #temp select 18, '01553', '20/02/2013 23:45:45.000'--ok

    insert into #temp select 19, '01553', '20/02/2013 23:45:45.200'

    ; with setrows

    as

    (

    select *

    , ROW_NUMBER() over (order by logtime asc) as rownum

    from #TEMP

    )

    select sr1.*, sr2.Logtime, DATEDIFF(ss,sr1.logtime,sr2.logtime) timeDifferential

    from setrows sr1

    inner join setrows sr2

    on sr1.rownum = sr2.rownum - 1

    set nocount off

    drop table #TEMP

    Hi Erin

    Yes, I would show the records thar are equal or more than 2 secons from the last valid record,

    sorry for the error,

  • Le Sigh.. for the life of me I cannot figure out how to do this in a set-based statement so slap me now.

    The following code will do what you want.

    if Object_id('tempdb..#TEMP') is not null

    DROP TABLE #temp

    set nocount on

    set dateformat dmy

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

    insert into #temp select 1, '01551', '20/02/2013 17:41:45.000' --ok

    insert into #temp select 19, '01551', '20/02/2013 17:41:45.400'

    insert into #temp select 20, '01551', '20/02/2013 17:41:45.700'

    insert into #temp select 8, '01551', '20/02/2013 17:41:45.800'

    insert into #temp select 2, '01551', '20/02/2013 17:41:45.900'

    insert into #temp select 9, '01551', '20/02/2013 17:41:45.950'

    insert into #temp select 21, '01551', '20/02/2013 17:41:46.100'

    insert into #temp select 3, '01551', '20/02/2013 17:41:46.150'

    insert into #temp select 22, '01551', '20/02/2013 17:41:46.990'

    insert into #temp select 31, '01551', '20/02/2013 17:41:47.140'--ok

    insert into #temp select 32, '01551', '20/02/2013 17:41:47.940'

    insert into #temp select 33, '01551', '20/02/2013 17:41:48.120'

    insert into #temp select 34, '01551', '20/02/2013 17:41:48.720'

    insert into #temp select 10, '01551', '20/02/2013 20:41:45.600'--ok

    insert into #temp select 11, '01551', '20/02/2013 20:41:45.900'

    insert into #temp select 4, '01551', '20/02/2013 20:41:47.000'

    insert into #temp select 35, '01551', '20/02/2013 20:41:47.100'

    insert into #temp select 36, '01551', '20/02/2013 20:41:47.600'--ok

    insert into #temp select 37, '01551', '20/02/2013 20:41:47.900'

    insert into #temp select 24, '01551', '20/02/2013 20:41:47.700'

    insert into #temp select 25, '01551', '20/02/2013 20:41:48.990'

    insert into #temp select 26, '01551', '20/02/2013 20:41:49.100'

    insert into #temp select 5, '01552', '20/02/2013 17:42:45.000'--ok

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 6, '01552', '20/02/2013 17:42:46.000'

    insert into #temp select 13, '01552', '20/02/2013 17:42:46.800'

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 27, '01552', '20/02/2013 17:42:46.100'

    insert into #temp select 28, '01552', '20/02/2013 17:42:46.600'

    insert into #temp select 29, '01552', '20/02/2013 19:45:45.400'--ok

    insert into #temp select 30, '01552', '20/02/2013 19:45:45.900'

    insert into #temp select 15, '01552', '20/02/2013 19:45:46.200'

    insert into #temp select 16, '01553', '20/02/2013 19:45:45.100'--ok

    insert into #temp select 17, '01553', '20/02/2013 19:45:45.600'

    insert into #temp select 18, '01553', '20/02/2013 23:45:45.000'--ok

    insert into #temp select 19, '01553', '20/02/2013 23:45:45.200'

    declare @validlogtime datetime

    set @validlogtime = (select top 1 logtime from #temp order by Logtime asc)

    select top 1 *

    into #resultset

    from #temp order by LogTime

    declare @test-2 varchar(10)

    declare dangit cursor for select Logtime from #temp order by Logtime asc

    open dangit

    fetch next from dangit into @validlogtime

    while @@FETCH_STATUS = 0

    begin

    if DATEDIFF(ss,(select max(logtime) from #resultset),@validlogtime)>=2

    begin

    insert into #resultset select * from #temp where Logtime = @validlogtime

    set @validlogtime = (select max(logtime) from #resultset)

    end

    fetch next from dangit into @validlogtime

    end

    select * from #resultset order by LogTime

    set nocount off

    close dangit

    deallocate dangit

    drop table #resultset

    drop table #TEMP

  • sorry but my results are these...

    1015512013-02-20 17:41:45.000

    31015512013-02-20 17:41:47.140

    5015522013-02-20 17:42:45.000

    16015532013-02-20 19:45:45.100

    10015512013-02-20 20:41:45.600

    4015512013-02-20 20:41:47.000

    26015512013-02-20 20:41:49.100

    18015532013-02-20 23:45:45.000

    for userId = 01552 only has one record when it should have two

    and for userid = 01551 has 5 records whe it should have 4...

    I know that it's so difficult and so piffling

  • it's due to the milliseconds.. let me take another look. I also overlooked that you were grouping by user so the criteria changes per user.

  • Don't use cursors!

    You can do it with quirky update method:

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

    insert into #TEMP select 1, '01551', '20/02/2013 17:41:45.000' --ok

    insert into #TEMP select 19, '01551', '20/02/2013 17:41:45.400'

    insert into #TEMP select 20, '01551', '20/02/2013 17:41:45.700'

    insert into #TEMP select 8, '01551', '20/02/2013 17:41:45.800'

    insert into #TEMP select 2, '01551', '20/02/2013 17:41:45.900'

    insert into #TEMP select 9, '01551', '20/02/2013 17:41:45.950'

    insert into #TEMP select 21, '01551', '20/02/2013 17:41:46.100'

    insert into #TEMP select 3, '01551', '20/02/2013 17:41:46.150'

    insert into #TEMP select 22, '01551', '20/02/2013 17:41:46.990'

    insert into #TEMP select 31, '01551', '20/02/2013 17:41:47.140'--ok

    insert into #TEMP select 32, '01551', '20/02/2013 17:41:47.940'

    insert into #TEMP select 33, '01551', '20/02/2013 17:41:48.120'

    insert into #TEMP select 34, '01551', '20/02/2013 17:41:48.720'

    insert into #TEMP select 10, '01551', '20/02/2013 20:41:45.600'--ok

    insert into #TEMP select 11, '01551', '20/02/2013 20:41:45.900'

    insert into #TEMP select 4, '01551', '20/02/2013 20:41:47.000'

    insert into #TEMP select 35, '01551', '20/02/2013 20:41:47.100'

    insert into #TEMP select 36, '01551', '20/02/2013 20:41:47.600'--ok

    insert into #TEMP select 37, '01551', '20/02/2013 20:41:47.900'

    insert into #TEMP select 24, '01551', '20/02/2013 20:41:47.700'

    insert into #TEMP select 25, '01551', '20/02/2013 20:41:48.990'

    insert into #TEMP select 26, '01551', '20/02/2013 20:41:49.100'

    insert into #TEMP select 5, '01552', '20/02/2013 17:42:45.000'--ok

    insert into #TEMP select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #TEMP select 6, '01552', '20/02/2013 17:42:46.000'

    insert into #TEMP select 13, '01552', '20/02/2013 17:42:46.800'

    insert into #TEMP select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #TEMP select 27, '01552', '20/02/2013 17:42:46.100'

    insert into #TEMP select 28, '01552', '20/02/2013 17:42:46.600'

    insert into #TEMP select 29, '01552', '20/02/2013 19:45:45.400'--ok

    insert into #TEMP select 30, '01552', '20/02/2013 19:45:45.900'

    insert into #TEMP select 15, '01552', '20/02/2013 19:45:46.200'

    insert into #TEMP select 16, '01553', '20/02/2013 19:45:45.100'--ok

    insert into #TEMP select 17, '01553', '20/02/2013 19:45:45.600'

    insert into #TEMP select 18, '01553', '20/02/2013 23:45:45.000'--ok

    insert into #TEMP select 19, '01553', '20/02/2013 23:45:45.200'

    SELECT IDENTITY(INT,1,1) RID,*, CAST(NULL AS BIT) AS Flag INTO #Work

    FROM #TEMP ORDER BY UserId, LogTime

    CREATE UNIQUE CLUSTERED INDEX ix_work ON #Work(RID, UserId, LogTime) -- very important!

    DECLARE @Flag BIT, @userid INT, @LastFlaggedLogTime DATETIME

    UPDATE w

    SET @Flag = Flag = CASE WHEN @userid IS NULL

    OR @userid != UserId

    OR DATEDIFF(millisecond,@LastFlaggedLogTime, Logtime) >= 2000

    THEN 1

    ELSE 0

    END

    ,@LastFlaggedLogTime = CASE WHEN @userid IS NULL

    OR @userid != UserId

    OR DATEDIFF(millisecond,@LastFlaggedLogTime, Logtime) >= 2000

    THEN Logtime

    ELSE @LastFlaggedLogTime

    END

    ,@UserId = UserId

    FROM #work AS w WITH (TABLOCKX) -- very important!

    OPTION (MAXDOP 1) -- very important!

    SELECT * FROM #Work WHERE Flag = 1

    Actually, you should be able to do it with using triangular join, but it will be much slower for sure.

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • It's hideous and I hate it but it does what you want.

    if Object_id('tempdb..#TEMP') is not null

    DROP TABLE #temp

    set nocount on

    set dateformat dmy

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

    insert into #temp select 1, '01551', '20/02/2013 17:41:45.000' --ok

    insert into #temp select 19, '01551', '20/02/2013 17:41:45.400'

    insert into #temp select 20, '01551', '20/02/2013 17:41:45.700'

    insert into #temp select 8, '01551', '20/02/2013 17:41:45.800'

    insert into #temp select 2, '01551', '20/02/2013 17:41:45.900'

    insert into #temp select 9, '01551', '20/02/2013 17:41:45.950'

    insert into #temp select 21, '01551', '20/02/2013 17:41:46.100'

    insert into #temp select 3, '01551', '20/02/2013 17:41:46.150'

    insert into #temp select 22, '01551', '20/02/2013 17:41:46.990'

    insert into #temp select 31, '01551', '20/02/2013 17:41:47.140'--ok

    insert into #temp select 32, '01551', '20/02/2013 17:41:47.940'

    insert into #temp select 33, '01551', '20/02/2013 17:41:48.120'

    insert into #temp select 34, '01551', '20/02/2013 17:41:48.720'

    insert into #temp select 10, '01551', '20/02/2013 20:41:45.600'--ok

    insert into #temp select 11, '01551', '20/02/2013 20:41:45.900'

    insert into #temp select 4, '01551', '20/02/2013 20:41:47.000'

    insert into #temp select 35, '01551', '20/02/2013 20:41:47.100'

    insert into #temp select 36, '01551', '20/02/2013 20:41:47.600'--ok

    insert into #temp select 37, '01551', '20/02/2013 20:41:47.900'

    insert into #temp select 24, '01551', '20/02/2013 20:41:47.700'

    insert into #temp select 25, '01551', '20/02/2013 20:41:48.990'

    insert into #temp select 26, '01551', '20/02/2013 20:41:49.100'

    insert into #temp select 5, '01552', '20/02/2013 17:42:45.000'--ok

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 6, '01552', '20/02/2013 17:42:46.000'

    insert into #temp select 13, '01552', '20/02/2013 17:42:46.800'

    insert into #temp select 12, '01552', '20/02/2013 17:42:45.500'

    insert into #temp select 27, '01552', '20/02/2013 17:42:46.100'

    insert into #temp select 28, '01552', '20/02/2013 17:42:46.600'

    insert into #temp select 29, '01552', '20/02/2013 19:45:45.400'--ok

    insert into #temp select 30, '01552', '20/02/2013 19:45:45.900'

    insert into #temp select 15, '01552', '20/02/2013 19:45:46.200'

    insert into #temp select 16, '01553', '20/02/2013 19:45:45.100'--ok

    insert into #temp select 17, '01553', '20/02/2013 19:45:45.600'

    insert into #temp select 18, '01553', '20/02/2013 23:45:45.000'--ok

    insert into #temp select 19, '01553', '20/02/2013 23:45:45.200'

    declare @validlogtime datetime

    set @validlogtime = (select top 1 logtime from #temp order by userid, Logtime asc)

    declare @userid varchar(10)

    declare @test-2 varchar(10)

    declare dangitusers cursor for select distinct userid from #TEMP order by UserID

    select top 1 * into #resultset from #TEMP where 1=0

    open dangitusers

    fetch next from dangitusers into @userid

    while @@FETCH_STATUS = 0

    begin

    insert into #resultset select top 1 *

    from #temp where userid = @userid order by userid, LogTime

    declare dangit cursor for select Logtime from #temp where userid = @userid order by userid asc , Logtime asc

    open dangit

    while @@FETCH_STATUS = 0

    begin

    select @userid, @validlogtime

    if DATEDIFF(ms,(select max(logtime) from #resultset where UserID = @userid),@validlogtime)>=2000

    begin

    insert into #resultset select * from #temp where Logtime = @validlogtime

    set @validlogtime = (select max(logtime) from #resultset where UserID = @userid )

    end

    fetch next from dangit into @validlogtime

    end

    close dangit

    deallocate dangit

    fetch next from dangitusers into @userid

    end

    select * from #resultset order by userid, LogTime

    set nocount off

    close dangitusers

    deallocate dangitusers

    drop table #resultset

    drop table #TEMP

  • You ran into the same issue I did, Eugene. User ms>2000 rather than seconds to meet his criteria but many thanks. I just could NOT figure out hot to set-base this.

    Great work!

  • fixed in my post...

    just replace

    DATEDIFF(second,@LastFlaggedLogTime, Logtime) >= 2

    with

    DATEDIFF(millisecond,@LastFlaggedLogTime, Logtime) >= 2000

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Perhaps this:

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

    set dateformat dmy;

    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 17:41:47.000'

    insert into #temp select 5, '01551 ', '20/02/2013 17:41:48.000'

    insert into #temp select 6, '01551 ', '20/02/2013 17:41:49.000'

    insert into #temp select 7, '01551 ', '20/02/2013 20:41:47.000'

    insert into #temp select 8, '01552 ', '20/02/2013 17:42:46.000'

    insert into #temp select 9, '01552 ', '20/02/2013 17:42:47.000'

    insert into #temp select 10, '01552 ', '20/02/2013 17:42:48.000'

    insert into #temp select 11, '01552 ', '20/02/2013 17:42:49.000'

    insert into #temp select 12, '01552 ', '20/02/2013 19:45:45.000'

    set dateformat mdy;

    declare @IntervalSeconds int = 2;

    with MinDate as (

    select cast(cast(min(LogTime) as date) as datetime) BaseDateTime from #temp

    ), BaseData as (

    select

    LogIndex,

    UserID,

    LogTime,

    BaseDateTime,

    BaseSeconds = datediff(second, BaseDateTime, LogTime),

    rn1 = row_number() over (partition by UserID, datediff(second, BaseDateTime, LogTime) order by LogTime),

    rn2 = dense_rank() over (partition by UserID order by datediff(second, BaseDateTime, LogTime))

    from

    #temp

    cross join MinDate

    ), SelectData as (

    select

    LogIndex,

    UserID,

    LogTime,

    rn = (row_number() over (partition by UserID, BaseSeconds - rn2 order by LogTime) - 1) % @IntervalSeconds

    from

    BaseData

    where

    rn1 = 1

    )

    select

    LogIndex,

    UserID,

    LogTime

    from

    SelectData

    where

    rn = 0;

    go

    DROP TABLE #temp

    go

  • Never mind on mine at the moment, needs more work. Have to look at it tonight.

Viewing 15 posts - 1 through 15 (of 37 total)

You must be logged in to reply to this topic. Login to reply