I have a query here which gives me the login times of staff. I would like it to just show me the latest most recent one. Here I can get the past 30 days but it is too many rows.
select distinct sv.staff_name, ul.session_start, ul.session_end, ul.ip_address
from use_log ul
inner join staff_view sv on ul.staff_id = sv.staff_id
where datediff(dd,ul.session_start, getdate()) <=30
always try to provide sample data. and also wrap your code with three of these tick marks `
select *
from (
select *,
ROW_NUMBER() OVER (
PARTITION BY sv.staff_id
ORDER BY ul.session_start desc
) row_num
from use_log ul
inner join staff_view sv on ul.staff_id = sv.staff_id
where datediff(dd,ul.session_start, getdate()) <=30
and ul.staff_id is not null
) a
where row_num = 1
; with cte as
(
select
distinct sv.staff_name
, ul.session_start
, ul.session_end
, ul.ip_address
from
use_log ul
inner join
staff_view sv on ul.staff_id = sv.staff_id
where
datediff(dd,ul.session_start, getdate()) <=30
and
ul.staff_id is not null
)
select
top 1 *
from
cte
order by
session_start desc
Never use functions on a table column in a WHERE clause, because that can prevent index seeks.
Also, you don't need a check for "ul.staff_id is not null" since if it were null, the inner join from ul would fail and exclude that row automatically any way.
Edit: Add DESC to the ORDER BY, to correct the query:
;WITH cte_ul_sv AS (
select distinct sv.staff_name, ul.session_start, ul.session_end, ul.ip_address,
row_number() over(partition by ul.staff_id order by ul.session_start DESC) as row_num
from dbo.use_log ul
inner join dbo.staff_view sv on ul.staff_id = sv.staff_id
where ul.session_start >= dateadd(day, -30, getdate()) --<<--<<--
)
select staff_name, session_start, session_end, ip_address
from cte_ul_sv
where row_num = 1
OOPS, SORRY, NO. The sort should be DESCending, so add DESC to the ORDER BY:
;WITH cte_ul_sv AS (
select distinct sv.staff_name, ul.session_start, ul.session_end, ul.ip_address,
row_number() over(partition by ul.staff_id order by ul.session_start DESC) as row_num --<<--<<--
from dbo.use_log ul
inner join dbo.staff_view sv on ul.staff_id = sv.staff_id
where ul.session_start >= dateadd(day, -30, getdate())
)
select staff_name, session_start, session_end, ip_address
from cte_ul_sv
where row_num = 1
DECLARE @number_of_days int
SET @number_of_days = 50
;WITH cte_ul_sv AS (
select distinct sv.staff_name, ul.session_start, ul.session_end, ul.ip_address,
row_number() over(partition by ul.staff_id order by ul.session_start **DESC** ) as row_num --<<--<<--
from dbo.use_log ul
inner join dbo.staff_view sv on ul.staff_id = sv.staff_id
where ul.session_start >= dateadd(day, @number_of_days, getdate())
)
select staff_name, session_start, session_end, ip_address
from cte_ul_sv
where row_num = 1