-2

我有一个查询,可以拉动用户打卡和打卡时间。我要做的是只返回第一个时钟时间和最后一个时钟时间的结果。

我的查询是:

SELECT
   lRecordID, lEmployeeID, dtTimeIn, dtTimeOut, sEnteredBy, sUpdatedBy, 
   dtUpdated, sDept, fHoursWorked, lDeptID, dblHourlyWage, fRegHours, dblRegLabor, 
   fOTHours, dblOTLabor, dtTimePunchIn, dtTimePunchOut, fPunchedHours
FROM            
   TimeClock
WHERE        
   (dtTimeIn > @startdate) AND (dtTimeOut < @enddate) AND (sDept IN ('1', '2', '3'))
4

5 回答 5

2

一种方法是使用以下row_number功能:

SELECT lRecordID, lEmployeeID, dtTimeIn, dtTimeOut, sEnteredBy, sUpdatedBy, 
       dtUpdated, sDept, fHoursWorked, lDeptID, dblHourlyWage, fRegHours, dblRegLabor, 
       fOTHours, dblOTLabor, dtTimePunchIn, dtTimePunchOut, fPunchedHours
FROM (select tc.*,
             row_number() over (partition by cast(dtTimeIn as date) order by dtTimeIn) as seqnum_asc,
             row_number() over (partition by cast(dtTimeIn as date) order by dtTimeIn desc) as seqnum_desc
     from TimeClock tc
     WHERE (dtTimeIn > @startdate) AND (dtTimeOut < @enddate) AND (sDept IN ('1', '2', '3'))
    ) tc
where seqnum_asc = 1 or seqnum_desc = 1

我假设 dtTimeIn 包含您要查找的日期和时间。

于 2012-12-17T20:07:40.120 回答
2

试试这个使用rank();

SELECT * FROM (
    SELECT lRecordID, lEmployeeID, dtTimeIn, dtTimeOut, sEnteredBy, 
       sUpdatedBy, dtUpdated, sDept, fHoursWorked, lDeptID, 
       dblHourlyWage, fRegHours, dblRegLabor, fOTHours, dblOTLabor, 
       dtTimePunchIn, dtTimePunchOut, fPunchedHours,
       RANK() OVER (ORDER BY dtTimeIn) rk1, --earliest record gets 1
       RANK() OVER (ORDER BY dtTimeOut DESC) rk2 --latest record gets 1

    FROM  TimeClock
    WHERE (dtTimeIn > @startdate) AND (dtTimeOut < @enddate) AND 
      (sDept IN ('1', '2', '3'))
) A
WHERE rk1=1 OR rk2=1

编辑 (1):使用Partitian by sDept编辑

编辑 (2):再次编辑删除Partitian by sDept

于 2012-12-17T20:13:53.557 回答
2

您可以使用子查询来执行此操作:

SELECT
   lRecordID, lEmployeeID, dtTimeIn, dtTimeOut, sEnteredBy, sUpdatedBy, 
   dtUpdated, sDept, fHoursWorked, lDeptID, dblHourlyWage, fRegHours, dblRegLabor, 
   fOTHours, dblOTLabor, dtTimePunchIn, dtTimePunchOut, fPunchedHours
FROM TimeClock c
LEFT JOIN
(
    select MIN(dtTimeIn) MindtTimeIn, CAST(dtTimeIn as DATE) dt
    from timeclock
    group by CAST(dtTimeIn as DATE)
) MinEmp
    on c.dtTimeIn = MinEmp.MindtTimeIn
    and CAST(c.dtTimeIn as DATE) = MinEmp.dt
LEFT JOIN
(
    select MAX(dtTimeOut) MaxdtTimeOut, CAST(dtTimeOut as DATE) dt
    from timeclock
    group by CAST(dtTimeOut as DATE)
) MaxEmp
    on c.dtTimeOut = MaxEmp.MaxdtTimeOut
    and CAST(c.dtTimeOut as DATE) = MaxEmp.dt
WHERE (dtTimeIn > @startdate) 
    AND (dtTimeOut < @enddate) 
    AND (sDept IN ('1', '2', '3'))

如果您没有使用 SQL Server 2008+,那么您没有DATE数据类型,因此您可以使用:

SELECT
   lRecordID, lEmployeeID, dtTimeIn, dtTimeOut, sEnteredBy, sUpdatedBy, 
   dtUpdated, sDept, fHoursWorked, lDeptID, dblHourlyWage, fRegHours, dblRegLabor, 
   fOTHours, dblOTLabor, dtTimePunchIn, dtTimePunchOut, fPunchedHours
FROM TimeClock c
LEFT JOIN
(
    select MIN(dtTimeIn) MindtTimeIn, Convert(char(10), dtTimeIn, 120) dt
    from timeclock
    group by Convert(char(10), dtTimeIn, 120)
) MinEmp
    on c.dtTimeIn = MinEmp.MindtTimeIn
    and Convert(char(10), c.dtTimeIn, 120) = MinEmp.dt
LEFT JOIN
(
    select MAX(dtTimeOut) MaxdtTimeOut, Convert(char(10), dtTimeOut, 120) dt
    from timeclock
    group by Convert(char(10), dtTimeOut, 120
) MaxEmp
    on c.dtTimeOut = MaxEmp.MaxdtTimeOut
    and Convert(char(10), c.dtTimeOut, 120 = MaxEmp.dt
WHERE (dtTimeIn > @startdate) 
    AND (dtTimeOut < @enddate) 
    AND (sDept IN ('1', '2', '3'))
于 2012-12-17T20:13:56.670 回答
0

你会想做:

SELECT [] FROM [] WHERE [] AND rownum = 1 ORDER BY timestamp DESC
UNION
SELECT [] FROM [] WHERE [] AND rownum = 1 ORDER BY timestamp ASC

可能有更好的方法可以做到这一点,但这无论如何都会让你得到答案。

于 2012-12-17T20:10:42.023 回答
-1

如果添加 ORDER BY dtTimeIn ASC 并限制 TOP 1 的行数,它将返回第一个打卡。如果添加 ORDER BY dtTimeOut DESC 并限制 TOP 1 的行数,它将显示最后一个打卡出去。您只需要合并这两个查询。

我没有尝试过,但它可能看起来像这样。

SELECT TOP 1 * FROM  (

SELECT
   lRecordID, lEmployeeID, dtTimeIn, dtTimeOut, sEnteredBy, sUpdatedBy, 
   dtUpdated, sDept, fHoursWorked, lDeptID, dblHourlyWage, fRegHours, dblRegLabor, 
   fOTHours, dblOTLabor, dtTimePunchIn, dtTimePunchOut, fPunchedHours
FROM            
   TimeClock
WHERE        
   (dtTimeIn > @startdate) AND (dtTimeOut < @enddate) AND (sDept IN ('1', '2', '3'))
ORDER BY dtTimeIn ASC
)

UNION 

SELECT TOP 1 * FROM (

SELECT
   lRecordID, lEmployeeID, dtTimeIn, dtTimeOut, sEnteredBy, sUpdatedBy, 
   dtUpdated, sDept, fHoursWorked, lDeptID, dblHourlyWage, fRegHours, dblRegLabor, 
   fOTHours, dblOTLabor, dtTimePunchIn, dtTimePunchOut, fPunchedHours
FROM            
   TimeClock
WHERE        
   (dtTimeIn > @startdate) AND (dtTimeOut < @enddate) AND (sDept IN ('1', '2', '3'))
ORDER BY dtTimeOut DESC

)
于 2012-12-17T20:07:14.510 回答