MS SQL query to show nearest date

k3vsmith
k3vsmith used Ask the Experts™
on
I have a query that selects users and login times. I only care about the latest login, not all of there logins.
My current query is showing all of there logins.

SELECT  
    ROLES.[USERID],
    ROLES.[ROLE],
	Activity.[SIGNON_TIME_STAMP]
FROM    
[Database].[Schema1].[table1] ROLES
LEFT JOIN
    [Database].[Schema2].[table1] Activity on ROLES.[USERID] = Activity.[SIGNON_USERID]
Order by ROLES.USERID

Open in new window


I tried using GETDATE() but may not be using it correctly.

I added a WHERE clause
WHERE Activity.[SIGNON_TIME_STAMP] > GETDATE()
but that just gives me same thing well minus about 50 rows?

Id like to see
userA role Lastlogindate

but am seeing
userA role logindate1
userA role logindate2
userA role logindate3
userA role logindate4

logindate (SIGNON_TIME_STAMP) should be either todays date or closest to it.

I should also mention the SIGNON_TIME_STAMP is formatted as such: 2017-03-17 15:21:00.460

Please help
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Mike EghtebasDatabase and Application Developer

Commented:
SELECT  * FROM    
(Select ROLES.[USERID], ROLES.[ROLE], ROW_NUMBER() OVER(PARTITION BY ROLES.[USERID] ORDER BY Activity.[SIGNON_TIME_STAMP] Desc) RN From [Database].[Schema1].[table1] ROLES
LEFT JOIN [Database].[Schema2].[table1] Activity on ROLES.[USERID] = Activity.[SIGNON_USERID]
WHERE RN=1 Order by ROLES.USERID)D

Open in new window

Naitik GamitSoftware Developer
Top Expert 2015
Commented:
SELECT  
    ROLES.[USERID],
    ROLES.[ROLE],
	MAX(Activity.[SIGNON_TIME_STAMP])
FROM    
[Database].[Schema1].[table1] ROLES
LEFT JOIN
    [Database].[Schema2].[table1] Activity on ROLES.[USERID] = Activity.[SIGNON_USERID]
GROUP BY ROLES.[USERID],ROLES.[ROLE]
Order by ROLES.USERID

Open in new window

PortletPaulEE Topic Advisor
Most Valuable Expert 2014
Awarded 2013

Commented:
If you only need the one date column from that activity table then using group by and max() should be fine. ROW_NUMBER() OVER() is my usual goto solution for this because it gives you access to complete rows of data unaffected by aggregate functions.

Here however I'm not sure why you are using a LEFT JOIN, perhaps to list users who have never logged on?
If you really need that to be effective you must table care the where clause does not inhibit rows without a join from the result.

Below I have used row_number() prior to the join and it allows the result to return unjoined users.
SELECT
      ROLES.[USERID]
    , ROLES.[ROLE]
    , Activity.[SIGNON_TIME_STAMP]
FROM [Database].[Schema1].[table1] ROLES
LEFT JOIN (
      SELECT
            [SIGNON_USERID]
          , [SIGNON_TIME_STAMP]
          , ROW_NUMBER() OVER (PARTITION BY [SIGNON_USERID] ORDER BY [SIGNON_TIME_STAMP] DESC) RN
      FROM [Database].[Schema2].[table1]
      ) Activity ON ROLES.[USERID] = Activity.[SIGNON_USERID]
                 AND Activity.[RN] = 1
ORDER BY ROLES.USERID
;

Open in new window

Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Author

Commented:
Naitik Gamit and PortletPaul - Your guys solutions are what I'm after. Thanks! Mike - I couldnt get yours to work.
And to answer PortletPaul, yes I also want to see users who have not logged in -reason for the Join.

So now I need to either create a view from this select and grant to a user or create a table from this select and grant to a user.
I suspect if I create a table, I'd have to set it up as a job, to drop table, recreate table and give grant possibly nightly...
Can I set this up as a view? Or would that still only give me the info as of the time the view was created?
User (granted user) wants to be able to come to this view/table any day and see who has what roles and the last time they have logged in.
How best to handle?
EE Topic Advisor
Most Valuable Expert 2014
Awarded 2013
Commented:
>>"Can I set this up as a view? "
Yes, absolutely. It will produce "current state" information when it is used.

I would not go down the create table rabbit hole.

So that we are clear:

>>" Or would that still only give me the info as of the time the view was created?"
NO! absolutely not. That is not what views do.

When you create a view it is the query CODE that gets "frozen in time", NOT the query result.

Did I mention? I would not go down the create table rabbit hole.

Oh, but one thing you never want to do in a view is use the final ORDER BY clause (this does not apply to the row_number calculation)

CREATE VIEW give_it_a_good_name_here AS

SELECT
      ROLES.[USERID]
    , ROLES.[ROLE]
    , Activity.[SIGNON_TIME_STAMP]
FROM [Database].[Schema1].[table1] ROLES
LEFT JOIN (
      SELECT
            [SIGNON_USERID]
          , [SIGNON_TIME_STAMP]
          , ROW_NUMBER() OVER (PARTITION BY [SIGNON_USERID] ORDER BY [SIGNON_TIME_STAMP] DESC) RN
      FROM [Database].[Schema2].[table1]
      ) Activity ON ROLES.[USERID] = Activity.[SIGNON_USERID]
                 AND Activity.[RN] = 1

Open in new window

/* ORDER BY ROLES.USERID  don't include THIS ROW */

Author

Commented:
Thank you!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial