2017-03-19 4 views
0

Meine Tabelle speichert Uhr out Zeiten, aber einige der sie mehr als 1 Mal Punch. Wie erhalte ich das letzte Ergebnis, wenn das Ergebnis mehr als eins ist?Nehmen Sie das letzte Ergebnis, wo Ergebnis mehr als eins

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 

Ausgang:

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 

sollte nur dieses Ergebnis zeigt sein:

RN USERID ClockOut CHECKTIME 
----------------------------------------------- 
1 6  11:31PM  2017-03-09 23:31:27.000 

Antwort

2

In Ihrem row_number(), Ihre order by zu l.CHECKTIME desc ändern und dann gefiltert werden where rn = 1 eine common table expression oder Unterabfrage.

Um den letzten Checkout pro Tag zu erhalten, ändern Sie Ihre partition by in l.userid, dateadd(day, datediff(day, 0, l.checktime), 0), um die Datetime auf das Datum zu kürzen (Sie könnten auch convert(date,l.checktime) verwenden).

mit einem common table expression:

;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; 

oder ohne 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; 

und einen schnelleren Weg auszuführen:

AND MONTH(CHECKTIME) = MONTH(getdate()) 
AND YEAR(CHECKTIME) = YEAR(getdate()) 

ist

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 */ 
Verwandte Themen