私たちの対話の後、また他の参加者とのあなたの対話を見直したところ、あなたの問題はもう少し制約されていることがわかりました. 実際に必要な出力は次のようなものです。
EMPID DAY WORKEDHOURS
1 2-9-2013 7:30
1 3-9-2013 8:30
2 2-9-2013 7:30
ケース 1: 範囲内の 1 日
1 日だけに関心がある場合は、結果に日付を挿入するだけです。次のことを試してください。
SELECT E.EMPID,
'2013-09-02' AS DAY,
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS
FROM EMPLOYEE_DETAILS E
LEFT JOIN TIMING_DETAILS TM
ON (E.EMPID=TM.EMPID)
WHERE TM.LOGIN BETWEEN '2013-09-02' AND DATEADD(DAY, 1, '2013-09-03')
GROUP BY E.EMPID
ORDER BY E.EMPID
問題の日付に名前付きパラメーターを使用するようにクエリを書き直すこともできます。以下に例を示しますが、これを使用するには、値を parameter にバインドする必要がありますTheDay
。
SELECT E.EMPID,
@TheDay AS DAY,
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS
FROM EMPLOYEE_DETAILS E
LEFT JOIN TIMING_DETAILS TM
ON (E.EMPID=TM.EMPID)
WHERE TM.LOGIN BETWEEN @TheDay AND DATEADD(DAY, 1, @TheDay)
GROUP BY E.EMPID
ORDER BY E.EMPID
ケース 2: 範囲内の複数日
EMPID ごとに複数の行が必要であるが、そのような行が 1 日に 1 つしかない場合、事態はさらに複雑になります。いくつかの (おそらくすべての) DBMS で可能だと思いますが、移植性のない機能を使用する必要があるかもしれません。必要なのは、日時値GROUP BY
の日の部分です。LOGIN
SQL Server 2008 (またはそれ以降) を使用している場合は、次のことを試すことができます。
SELECT E.EMPID,
CAST(TM.LOGIN AS DATE) AS DAY,
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS
FROM EMPLOYEE_DETAILS E
LEFT JOIN TIMING_DETAILS TM
ON (E.EMPID=TM.EMPID)
WHERE TM.LOGIN BETWEEN '2013-09-02' AND DATEADD(DAY, 1, '2013-09-03')
GROUP BY E.EMPID, CAST(TM.LOGIN AS DATE)
ORDER BY E.EMPID
私はこのクエリをテストする立場にないことに注意してください。たとえば、GROUP BY DAY
式を繰り返す代わりに、そうしなければならない場合があります。
ケース 2B: 範囲内の複数日、最初と最後のログイン
EMPID ごとに 1 日 1 行が必要ですが、最初のログイン時間と最後のログアウト時間は必要ですか? 次のことを試すことができます。
SELECT E.EMPID,
MIN(TM.LOGIN) AS FIRSTLOGIN,
MAX(TM.LOGOUT) AS LASTLOGOUT,
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS
FROM EMPLOYEE_DETAILS E
LEFT JOIN TIMING_DETAILS TM
ON (E.EMPID=TM.EMPID)
WHERE TM.LOGIN BETWEEN '2013-09-02' AND DATEADD(DAY, 1, '2013-09-03')
GROUP BY E.EMPID, CAST(TM.LOGIN AS DATE)
ORDER BY E.EMPID
繰り返しますが、私はこのクエリをテストする立場にありませんでした。
テスト ケース: Visual Studio 2010 内のローカル SQL Server Express データベースに対するクエリ
今日は Sql Server でテストできませんが、ローカルの Sql Server Express データベースで Visual Studio 2010 の下でテストしたバージョンのクエリを次に示します。
SELECT
E.EMPID, E.NAME,
MIN(TM.LOGIN) AS FirstLogIn,
MAX(TM.LOGOUT) AS LastLogOut,
CAST(SUM(DATEDIFF(MINUTE, TM.LOGIN, TM.LOGOUT) / 60) AS NVARCHAR)+':'+CAST(SUM(DATEDIFF(MINUTE, TM.LOGIN, TM.LOGOUT) % 60) AS NVARCHAR) AS WorkedHours
FROM
EMPLOYEE_DETAILS AS E LEFT OUTER JOIN TIMING_DETAILS AS TM ON E.EMPID = TM.EMPID
WHERE
TM.LOGIN BETWEEN '2013-09-21' AND DATEADD(DAY, 1, '2013-09-22')
GROUP BY
E.EMPID, E.NAME,
DATEADD(DAY, DATEDIFF(DAY, 0, TM.LOGIN), 0)
ORDER BY
E.EMPID, FirstLogin
テスト データ EMPLOYEE_DETAILS:
EMPID NAME
1 Joe
2 Jane
3 Martha
テストデータ TIMING_DETAILS:
EMPID LOGIN LOGOUT
1 '2013-09-21 09:00:00' '2013-09-21 10:30:00'
1 '2013-09-21 14:00:00' '2013-09-21 16:00:00'
1 '2013-09-22 08:30:00' '2013-09-22 11:00:00'
2 '2013-09-21 10:45:00' '2013-09-21 13:30:00'
結果:
EMPID NAME FirstLogIn LastLogOut WorkedHours
1 Joe '2013-09-21 09:00:00' '2013-09-21 16:00:00' 3:30
1 Joe '2013-09-22 08:30:00' '2013-09-22 11:00:00' 2:30
2 Jane '2013-09-21 10:45:00' '2013-09-21 13:30:00' 2:45
それは私には正しいようです。SQL Server Express クエリの唯一の違いは、DATE 型が提供されていないことです。そのため、CAST を変更する必要がありました。ああ、WorkedHours の NVARCHAR にも明示的にキャストする必要がありました。
ご使用の環境に合わせて調整してください。
お役に立てれば。