简体   繁体   中英

to find who logged in first in given interval of time sql

This is a dummy script :

create table #tempLogs (
UserId int identity(1,1) primary key,
LoggedAt DateTime not null
)
insert into #tempLogs values(getdate())
insert into #tempLogs values(getdate()-0.05)
insert into #tempLogs values(getdate()+0.0075)
select * from #tempLogs

SELECT top 1 UserId, (SUBSTRING((CONVERT(VARCHAR(20), LoggedAt)),13,5)) 
from #tempLogs
order by 2 


drop table #tempLogs

How can I optimize :

SELECT top 1 UserId, (SUBSTRING((CONVERT(VARCHAR(20), LoggedAt)),13,5)) 
    from #tempLogs


where between @StartDate and @EndDate -- for some time interval. These are inputs  & need to be passed

order by 2 

Top 1 is actually not a right solution there can be more than 1 User coming on same minute ie 9:27 9:27

Here, temptables are just used actually query would be fired on actual tables & not temporary.

Need advice on optimizing this.

Example :

UserId  LoggedAt
1       2011-12-22 11:44:31.037
2       2011-12-22 10:32:31.040
3       2011-12-22 11:55:19.040
4       2011-12-22 10:32:31.040

Output

2       2011-12-22 10:32:31.040
4       2011-12-22 10:32:31.040

thats it!

Current best guess at the required answer:

If you need to get the first "with ties", then:

;WITH RankedLogs as (
    SELECT ID,LoggedAt,RANK() OVER (ORDER BY LoggedAt) as rn
    from #tempLogs where LoggedAt between @StartDate and @EndDate
)
SELECT * from RankedLogs where rn = 1

Or, if two logins within the same minute should rank together then:

;WITH RankedLogs as (
    SELECT ID,LoggedAt,RANK() OVER (ORDER BY DATEADD(minute,DATEDIFF(minute,0,LoggedAt),0)) as rn
    from #tempLogs where LoggedAt between @StartDate and @EndDate
)
SELECT * from RankedLogs where rn = 1

Previous answers:

Completely random guess - you want to find the earliest login within each hour long interval. Assuming same setup script as per your question:

;With RankedLogins as (
    Select UserID,LoggedAt,ROW_NUMBER() OVER (PARTITION BY DATEADD(hour,DATEDIFF(hour,0,LoggedAt),0) ORDER BY LoggedAt) as rn
    from #tempLogs
)
select * from RankedLogins where rn = 1

Result from table setup:

UserId  LoggedAt
1       2011-12-22 11:44:31.037
2       2011-12-22 10:32:31.040
3       2011-12-22 11:55:19.040

And results:

UserID  LoggedAt                rn
2       2011-12-22 10:32:31.040 1
1       2011-12-22 11:44:31.037 1

To find who logged in first on each day, change the two instances of hour in the above query to day .


For your simpler question (basically, find the earliest row between @StartDate and @EndDate ), it could just be:

SELECT top 1 * from #tempLogs
where LoggedAt between @StartDate and @EndDate
order by LoggedAt

To get the User with the minimal LoggedAt value is like this:

create table #tempLogs (
UserId int identity(1,1) primary key,
LoggedAt DateTime not null
)
insert into #tempLogs values(getdate())
insert into #tempLogs values(getdate()-0.05)
insert into #tempLogs values(getdate()+0.0075)


SELECT UserId, convert(varchar(5), LoggedAt, 108)
from #tempLogs
where LoggedAt = (select min(LoggedAt) from #tempLogs)




drop table #tempLogs

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