2017-01-26 7 views
-2

従業員のIDカードのトランザクションをスワイプしてスワイプしたテーブルがあります。 列:従業員ID、従業員名、日付と時間でスワイプし、日付と時刻をスワイプします。従業員がいなかった日付を取得するSQLクエリ

従業員IDと欠席日を取得するには、動作するMS SQL Serverクエリが必要です。

(注:追加のテーブル(複数可)の質問に答えるために作成することができる)

+4

あなたはおそらく、すべての作業日が含まれている。このため、カレンダーのテーブルを使用する必要があります。次に、このテーブルに参加して欠席を見つける。 –

+1

どのDBMSを使用していますか? – Hambone

+0

@TimBiegeleisenは正しかった。あなたは休暇日を別のテーブルに保存する必要があります。両方のテーブルに参加した後に.. – Darshak

答えて

7

他の人に言われているように、すべての就業日を格納するテーブルを持つのに役立ちます。簡単にするため、これはbusiness_calendarと名付けられ、working_dayという名前のDATETIME列にすべての就業日を格納するとします。使用しているSQL Serverのバージョンがわからないので、私はDATETIMEを使用します。そのため、日付のみを表すものは時間のない部分になります。 This answerは、比較時に時間部分を削除する方法について相談するのに便利です。

安全面でエラーが発生する場合は、従業員がスワイプイン/アウトの記録がない日付のみを照会することをおすすめします。これは深夜以降に働く従業員などのエッジケースに対応している場合があります。もしかしたらNULL何らかの理由で、スワイプインまたはスワイプアウトのいずれかが登録されませんでした。

単一従業員の欠席日数を見つけるには:

DECLARE @emp_id INT; 
SET @emp_id = 1; 

SELECT @emp_id AS employee_id, bc.working_day AS absent_day 
FROM business_calendar bc 
WHERE NOT EXISTS (
    SELECT * 
    FROM attendance a 
    WHERE a.employee_id = @emp_id 
     AND (DATEADD(day, DATEDIFF(day, 0, a.swipe_in), 0) = bc.working_day 
      OR DATEADD(day, DATEDIFF(day, 0, a.swipe_out), 0) = bc.working_day)); 

...またはすべての従業員と、彼らは欠席した日付のリストを取得するには、CROSS JOINを使用することができます。

SELECT e.id AS employee_id, bc.working_day AS absent_day 
FROM business_calendar bc 
CROSS JOIN employee e 
WHERE NOT EXISTS (
    SELECT * 
    FROM attendance a 
    WHERE a.employee_id = e.id 
     AND (DATEADD(day, DATEDIFF(day, 0, a.swipe_in), 0) = bc.working_day 
      OR DATEADD(day, DATEDIFF(day, 0, a.swipe_out), 0) = bc.working_day)); 

これはもちろん、従業員のサブセットおよび/または日付をANDさらにWHERE条件で含めるように簡単にフィルタリングすることができます。ここ

デモ:http://rextester.com/VPTTM33285

0

私は(唯一swipe_in、swipe_outを無視して)なされた仮定に基づいて、これは動作するはず。また、ここに月の日付範囲があると仮定します。私はテーブル生成の例をthisから使用しました。

DECLARE @StartDate DATETIME 
SET @StartDate = DATEADD(Month,-1,GetDate()) 
Declare @EndDate DATETIME 
SET @EndDate = Getdate() 

SELECT * From (
SELECT * FROM EmployeeAttendance EA 
RIGHT OUTER JOIN (
SELECT DATEADD(DAY, nbr - 1, @StartDate) as CalenderDate 
FROM (SELECT ROW_NUMBER() OVER (ORDER BY c.object_id) AS Nbr 
      FROM  sys.columns c 
     ) nbrs 
WHERE nbr - 1 <= DATEDIFF(DAY, @StartDate, @EndDate) 
) A1 ON (Dateadd(dd,0,Datediff(dd,0,A1.CalenderDate)) = DateAdd(dd,0,Datediff(dd,0,EA.SwipeIn))))A2 
WHERE Name IS NULL