Today at work we got into a discussion about which is the best way to do a query like this :
For instance lets assume a users table :
tblUsers
ID = Autoint
Name = String
and a login table :
tblLogin
ID = AUtoint
UserID = Int
IP = String
Browser = String
OS = String
timestamp = DateTime
What would be the most efficient way to list all the users and the last time they logged in (if ever), and provide an output like :
user | ip | timestamp | browser | os |
-------------------------------------------------
Some User |1.1.1.1 | 12/12/12 | userBA | win |
Other User |1.1.1.1 | 12/12/12 | userBA | win |
And Other |null | null | null | null |
Other Yet |1.1.1.1 | 12/12/12 | userBA | win |
Keep in mind that what we want here is to show all users exactly once even if he has never logged in, and only the most recent login (i.e max(timestamp)).
Is there a way to do it in one SQL statement?
We are using MSSQL 2005.
Thanks in advance guys, Jim
Im my opinion, the most readable way uses
row_number(). You can use it to number rows, starting with 1 for each user, like:A filter on
rn = 1gives the latest row per user. A subquery is required because SQL Server 2005 does not allow you to reference arow_number()in awhereclause.The most efficient way to do this depends on the amount of logins per user. You can find a good explanation of some of the more advanced methods in this blog post.