-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

サブクエリを使用してこれを実行できます。

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 に答える
2

これを行う 1 つの方法は、次の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): sDeptで編集Partitian by

編集 (2):削除されたPartitian by sDeptを再度編集しました。

于 2012-12-17T20:13:53.557 に答える
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 で行数を制限すると、最後にクロックインしたものが表示されますアウト。これら 2 つのクエリを結合するだけです。

試したことはありませんが、こんな感じかもしれません。

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 に答える