كيف يمكنني حساب الفترات الزمنية من قائمة تسجيل الوصول والمغادرة؟

StackOverflow https://stackoverflow.com/questions/275562

سؤال

أنا أكتب برنامجًا بسيطًا لتتبع الوقت لإدارة مشاريعي الخاصة.أنا من أشد المعجبين بالاحتفاظ بكود التقارير في قاعدة البيانات، لذلك كنت أحاول إنشاء عدد قليل من sprocs التي تولد الفواتير والجداول الزمنية وما إلى ذلك.

لدي جدول يحتوي على "إجراءات الساعة" و"Punch In" و"Punch Out" على IE.ويحتوي أيضًا على المستخدم الذي قام بهذا الإجراء، والمشروع المرتبط بالإجراء، والتاريخ/الوقت الحالي.

يمكنني الاختيار من هذا الجدول للحصول على ساعة دخول لوقت/مشروع/ومستخدم محدد، ولكنني أريد تجميعها بحيث يتم تحويل كل ساعة دخول وخروج من صفين إلى صف واحد يحتوي على الوقت الإجمالي.

على سبيل المثال، هنا إخراج عينة:

ClockActionID        ActionType DateTime
-------------------- ---------- -----------------------
17                   1          2008-11-08 18:33:56.000
18                   2          2008-11-08 18:33:59.587
19                   1          2008-11-08 18:34:01.023
20                   2          2008-11-08 18:34:02.037
21                   1          2008-11-08 18:45:06.317
22                   2          2008-11-08 18:46:14.597
23                   1          2008-11-08 18:46:16.283
24                   2          2008-11-08 18:46:17.173
25                   1          2008-11-08 18:50:37.830
26                   2          2008-11-08 18:50:39.737
27                   1          2008-11-08 18:50:40.547

(11 row(s) affected)

حيث ActionType 1 هو "ClockIn" و ActionType 2 هو "ClockOut".لقد قمت أيضًا بقص أعمدة المستخدم والمشروع والوصف للإيجاز.

أحتاج إلى إنشاء مجموعة نتائج في SQL خالصة مثل:

Description   |    Total Time

لكل زوج ClockIn / ClockOut.

أعتقد أن هذا سيكون في الواقع بسيطًا إلى حد ما، لكنني لست متأكدًا تمامًا من الطريقة التي سأتعامل بها معه.

يحرر:سيتمكن المستخدم من تسجيل الدخول في مشاريع متعددة في وقت واحد، على الرغم من أنه من خلال تضييق نطاق النتائج أولاً إلى مشروع واحد، لا ينبغي أن يحدث هذا أي فرق في المنطق هنا.

هل كانت مفيدة؟

المحلول

أوافق على أن التصميم ليس هو الأفضل - فالبنية القائمة على الحدث والتي تحتوي على صف واحد للبداية والنهاية ستوفر لك على الأرجح الكثير من الوقت.في هذه الحالة، يمكنك إنشاء سجل بتاريخ انتهاء فارغ عندما يقوم شخص ما بتسجيل الدخول.ثم قم بملء تاريخ الانتهاء عند انتهاء الوقت.

لكن هذا ليس ما طلبته.هذا هو الحل لمشكلتك:

DECLARE @clock TABLE (ClockActionID INT PRIMARY KEY IDENTITY, ActionType INT, ActionDateTime DATETIME)

INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:00:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:01:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:02:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:03:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:04:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:05:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:06:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:07:00')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (1,'20080101 00:08:12')
INSERT INTO @clock (ActionType, ActionDateTime) VALUES (2,'20080101 00:09:00')

-- Get the range
SELECT ActionDateTime CheckIn, 
  (SELECT TOP 1 ActionDateTime 
   FROM @clock C2 
   WHERE C2.ActionDateTime > C.ActionDateTime) CheckOut   
FROM @clock C
WHERE ActionType = 1

-- Get the duration
SELECT DATEDIFF(second, ActionDateTime, 
  (SELECT TOP 1 ActionDateTime 
   FROM @clock C2 
   WHERE C2.ActionDateTime > C.ActionDateTime)
  ) / 60.0 Duration_Minutes
FROM @clock C
WHERE ActionType = 1

لاحظ أنني أستخدم متغير جدول يعمل مع MS SQL Server للاختبار فقط.التغيير حسب الحاجة.لاحظ أيضًا أن SQL Server 2000 لا يؤدي بشكل جيد مع مثل هذه الاستعلامات.وهنا نتائج الاختبار:

CheckIn                 CheckOut
2008-01-01 00:00:00.000 2008-01-01 00:01:00.000
2008-01-01 00:02:00.000 2008-01-01 00:03:00.000
2008-01-01 00:04:00.000 2008-01-01 00:05:00.000
2008-01-01 00:06:00.000 2008-01-01 00:07:00.000
2008-01-01 00:08:12.000 2008-01-01 00:09:00.000

Duration_Minutes
1.000000
1.000000
1.000000
1.000000
0.800000

نصائح أخرى

وأعتقد أن لديك مخطط التخزين الأصلي هو معيب. كنت تبحث في ذلك من وجهة نظر على مدار الساعة، وبالتالي ClockAction. لماذا لا من وجهة نظر المشروع؟

والجدول ProjectAction (Projectid، حاليا، النوع، تشغيل، نهاية)

وبعد ذلك مجموعة بسيطة BY يجب أن تفعل خدعة.

هل فكرت في أشياء مثل:

  • هل نسي شخص ما تسجيل الخروج، وبالتالي يبدو أنه قام بتسجيل الدخول مرتين؟
  • هل نسي شخص ما تسجيل الدخول، وبالتالي يبدو أنه سجل خروجه مرتين؟

في الحالة الأولى، هل من الصحيح تجاهل الساعة الثانية ببساطة؟ستربط الإجابة المقبولة كلتا الساعة الإضافية وساعة الخروج نفسها.هل هذا صحيح؟

وفي الحالة الثانية، سيتم تجاهل انتهاء الساعة الثانية.هل هذا صحيح؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top