我的表存储时钟输出时间,但其中一些会打出超过1次。如何获得结果不止一个的最新结果?
SELECT
ROW_NUMBER() OVER (PARTITION BY l.USERID, day(l.CHECKTIME), DATEPART(hh, l.CHECKTIME) ORDER BY (select 0)) RN,
l.USERID,
CASE
WHEN CAST(l.CHECKTIME AS TIME) > = CAST(SC.EndTime AS TIME)
THEN CONVERT(VARCHAR(10), CAST(l.CHECKTIME AS TIME), 100)
ELSE 'Early ClockOut ' + CONVERT(VARCHAR(100), CAST(l.CHECKTIME AS TIME), 100)
END as ClockOut,l.CHECKTIME
FROM
CHECKINOUT l
INNER JOIN
USERINFO u ON l.USERID = u.USERID
INNER JOIN
UserUsedSClasses uuc ON uuc.USERID = u.USERID
INNER JOIN
SchClass SC ON uuc.SchId = SC.schClassid
WHERE
u.BADGENUMBER not in (79,103,78)
AND MONTH(CHECKTIME) = MONTH(getdate()) AND YEAR(CHECKTIME) = YEAR(getdate())
AND uuc.SchId = 1
AND DATEPART (hh, l.CHECKTIME) >= DATEPART(hh, SC.EndTime)
AND DATEPART(hh, l.CHECKTIME) >= DATEPART (hh, SC.StartTime)
ORDER BY
u.BADGENUMBER
输出:
RN USERID ClockOut CHECKTIME
1 6 7:04PM 2017-03-09 19:04:12.000
2 6 7:55PM 2017-03-09 19:55:59.000
1 6 11:31PM 2017-03-09 23:31:27.000
应仅显示此结果:
RN USERID ClockOut CHECKTIME
-----------------------------------------------
1 6 11:31PM 2017-03-09 23:31:27.000
答案 0 :(得分:2)
在row_number()
中,将order by
更改为l.CHECKTIME desc
,然后使用common table expression或子查询过滤where rn = 1
。
要每天获取最新结帐,请将partition by
更改为l.userid, dateadd(day, datediff(day, 0, l.checktime), 0)
,将日期时间截断为日期(您也可以使用convert(date,l.checktime)
)。
;with cte as (
select
rn = row_number() over (
partition by l.userid, dateadd(day, datediff(day, 0, l.checktime), 0)
order by l.checktime desc
)
, l.userid
, Clockout = case
when cast(l.checktime as time) >= cast(sc.EndTime as time)
then convert(varchar(100), cast(l.checktime as time), 100)
else 'Early ClockOut ' + convert(varchar(100), cast(l.checktime as time), 100)
end
, l.checktime
, u.badgenumber
from checkinout l
inner join userinfo u
on l.userid = u.userid
inner join UserUsedsclasses uuc
on uuc.userid = u.userid
inner join SchClass sc
on uuc.SchId = sc.schClassid
where uuc.SchId = 1
and u.badgenumber not in (79, 103, 78)
and l.checktime >= dateadd(month, datediff(month, 0, getdate() ) , 0)
and l.checktime < dateadd(month, datediff(month, 0, getdate() )+1, 0)
and datepart(hour, l.checktime) >= datepart(hour, sc.EndTime)
and datepart(hour, l.checktime) >= datepart(hour, sc.StartTime)
)
select *
from cte
where rn = 1
order by badgenumber;
或没有cte
select *
from (
select
rn = row_number() over (
partition by l.userid, dateadd(day, datediff(day, 0, l.checktime), 0)
order by l.checktime desc
)
, l.userid
, Clockout = case
when cast(l.checktime as time) >= cast(sc.EndTime as time)
then convert(varchar(100), cast(l.checktime as time), 100)
else 'Early ClockOut ' + convert(varchar(100), cast(l.checktime as time), 100)
end
, l.checktime
, u.badgenumber
from checkinout l
inner join userinfo u
on l.userid = u.userid
inner join UserUsedsclasses uuc
on uuc.userid = u.userid
inner join SchClass sc
on uuc.SchId = sc.schClassid
where uuc.SchId = 1
and u.badgenumber not in (79, 103, 78)
and l.checktime >= dateadd(month, datediff(month, 0, getdate() ) , 0)
and l.checktime < dateadd(month, datediff(month, 0, getdate() )+1, 0)
and datepart(hour, l.checktime) >= datepart(hour, sc.EndTime)
and datepart(hour, l.checktime) >= datepart(hour, sc.StartTime)
) as sub
where rn = 1
order by badgenumber;
更快的执行方式:
AND MONTH(CHECKTIME) = MONTH(getdate())
AND YEAR(CHECKTIME) = YEAR(getdate())
是
and l.checktime >= dateadd(month, datediff(month, 0, getdate() ) , 0) /* month start*/
and l.checktime < dateadd(month, datediff(month, 0, getdate() )+1, 0) /* next month start */