如何使用最早的时间戳和最新的时间戳返回记录

时间:2012-12-17 19:57:20

标签: sql sql-server

我有一个查询可以拉动用户的时钟和时钟。我要做的是仅返回FIRST时钟的结果和最后的时钟输出时间。

我的查询是:

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'))

5 个答案:

答案 0 :(得分: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包含您要查找的日期和时间。

答案 1 :(得分: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

答案 2 :(得分: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'))

答案 3 :(得分:0)

你想要这样做:

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

可能有更好的方法可以做到这一点,但无论如何这将为您提供答案。

答案 4 :(得分:-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

)