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!
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.