简体   繁体   中英

SQL Date Ignore few seconds difference and fetch latest record

We have Service One that creates user details in one place and sent to other Service two with the creation date.The other service uses the same creation date, so in both places it will be the same creation date!

However, we missed to send creation date initially and fixed it later. We found that many record has 1-3 seconds difference and we ended up getting duplicates as we cant filter them for 1-3 seconds.

When query the Service Two database we need to ensure we get the latest record for a person with the date created by Service One and ignore the Service Two created date if they 1-3 seconds difference.

Below is the table with data here is DB Fiddle

在此处输入图像描述

I wrote a below query but it always pull everything still

SELECT DataId, PersonId, CreatedOn 
FROM PersonDetails 
WHERE PersonId = 310256
    and DATEDIFF(Second,DATEADD(SS,3,CreatedOn),CreatedOn) < 3

I want to fetch DataId 2 and 7 (Latest) but the older date record.

Note: Person can have 1 or more records created on the same day, time, but they cant create less than 3 secs: Example there can be another valid record '2022-01-17 15:42.00,1400000', In that case I want to include this as well

this can work if your dataid is chronologically incremented, and based on your tiny sample data, with same events within 3sec

SELECT [dataId]=max(DataId) 
FROM PersonDetails 
WHERE PersonId = 310256
group by (datediff(second,'20000101',CreatedOn)/3)*3

dbfiddle

Is this what you want?

select t.DataId, t.PersonId, t.CreatedOn
from  ( SELECT max(DataId) as DataId, PersonId, CreatedOn 
        FROM  PersonDetails 
        WHERE PersonId = 310256
        group by PersonId, CreatedOn 
      ) t
where not exists ( select 1 from PersonDetails p
                   where  p.PersonId = t.PersonId
                   and    p.DataId <> t.DataId
                   and    p.CreatedOn < t.CreatedOn
                   and    dateadd(second, 3, p.CreatedOn) >= t.CreatedOn
                 )

Result:

DataId  PersonId    CreatedOn
2       310256      2022-01-17 15:37:01.9400000
7       310256      2022-01-17 15:41:01.9400000

DBFiddle

Edit

When I read your explanation, I think you need row 2 and 4 instead of 2 and 7

That would be more like this

select t.PersonID, 
       t.CreatedOn,
       p2.DataId
from   ( SELECT Min(PersonID) as PersonID, 
                max(CreatedOn) as CreatedOn
         FROM   PersonDetails 
         WHERE  PersonId = 310256
         group by (datediff(second,'20000101',CreatedOn)/3)*3
       ) t
  outer apply ( select top 1 p.DataId 
                from   PersonDetails p
                where  p.PersonId = t.PersonId 
                and    p.CreatedOn = t.CreatedOn
                order by p.CreatedOn desc, p.DataId desc
              ) p2

DBFiddle

or also like this, build on the answer of @jjdesign

SELECT p.PersonID,
       max(p.CreatedOn) as CreatedOn,
       ( select top 1 p2.DataId
         from   PersonDetails p2
         where  p2.PersonID = p.PersonID
         and    p2.CreatedOn = max(p.CreatedOn)
         order by p2.CreatedOn desc, p2.DataId desc
       ) as DataId
FROM   PersonDetails p
WHERE p.PersonId = 310256
group by p.PersonID, (datediff(second,'20000101',CreatedOn)/3)*3

DBFiddle

This seems to work:

SELECT 
    *
FROM PersonDetails d
WHERE DataID = (SELECT TOP 1 DataID
                FROM PersonDetails d2
                WHERE d.CreatedON BETWEEN d2.CreatedON AND DATEADD(SS,3,CreatedOn) 
                ORDER BY DataID DESC
                      )

see: dbfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM