2011-08-30 222 views
0

嘿家伙,我试图帮助我的朋友设计数据库表。这是一个通过读取某些读卡器的卡信息来跟踪工厂工作时间的系统。每次工作人员记录他的进出信息时,都会保存一条记录。如何设计工作时间的数据库表?

我的问题是,我怎么能计算出每个工人的工作时间(以分钟为单位),每个工作日?工作人员可以在上午8:00至20:00或下午20:00〜8:00AM工作。

任何人都可以帮到我吗?

谢谢!


你们确实给了我很多帮助。 以前的设计是一张有记录或无记录的表格。我很难找到哪些属于同一个工作时间跨度。我现在使用另一张带有记录的表格,它们在同一个记录中都有时间和空闲时间。插入以节省时间,更新以节省停工时间,这使得计算准时和停工时间之间的总分钟变得容易。

+0

您正在使用哪个版本的SQL Server? –

+0

SQL Server 2005 – Soony

+0

如果午夜在当前工作会话之间,该怎么办?整个工作时间都在计算工人开始工作的那一天或他结束工作的那一天,还是你必须在午夜之前分工? –

回答

3
SELECT datediff(hh,'2011-08-30 04:47','2011-08-30 05:48') as [Hour(s) Worked] 
Hour(s) Worked 
-------------- 
1 
+0

datediff(mi,...)会计算分钟 –

+0

'DATEDIFF(hh,...)'会给你奇怪的结果。请阅读我的答案。 –

2

有2个表

[TblUsers] 
User_id  PK 
FirstName 
LastName 

[TblSchedule] 
Schedule_id PK 
User_id  FK 
Date_From 
Date_To 

一个简单的例子来获得与次日常工作网格,你可以写这样的:

SELECT 
    u.FirstName + ' ' + u.LastName as [username], 
    CAST(FLOOR(CAST(@datetime as float)) as datetime) as [date], 
    DATEDIFF(minute, s.Date_To, s.Date_From) as [workMinutes] 
FROM 
    [TblSchedule] s, [TblUsers] u 
WHERE 
s.user_id = u.user_id 
GROUP BY 
    u.FirstName + ' ' + u.LastName, 
    CAST(FLOOR(CAST(@datetime as float)) as datetime) 
ORDER BY 
s.Date_From; 
+0

我只是不能用表名,对不起。请考虑'User'(或'SystemUser'以避免关键字冲突)和'Schedule'而不是使用前缀。 – Yuck

+0

他有一个带有“IN-Record”和“OUT-Records”的表格。此外,我确信它必须为每天的多次入住和退房做好准备,即工作人员正在退房吃午饭,之后再次入住。 –

1

只需计算出每个IN-Record及以下OUT-Record之间的分钟数来自这名工人。如果你想要一整天,然后获取相关记录并总结相关的差异。

更复杂这里的事情是当一些工人忘记冲压。你的计划必须为这种情况做好准备。

也要注意夏令时等。时间计算器可能非常复杂。

我想我会做的应用水平计算,而不是在SQL在这种情况下。

0

DATEDIFF可以给你一些奇怪的结果。 例如采取这种两DATETIME2(我相信你有SQL Server 2008中)有5分钟的差值:

SELECT DATEDIFF(hh,'2011-01-01 04:59:00','2011-01-01 05:04:00') 
Results 
----------- 
1 

结果是莫名其妙奇怪:1小时。奇怪,因为分钟的差异是5分钟,但是小时的差别是1小时,我们知道1小时= 60分钟。请阅读此article以查看解释。

解决方案:

1)代替DATEDIFF(hh,...)使用DATEDIFF(mi,...) 例:

SELECT DATEDIFF(mi,'2011-01-01 07:55:00','2011-01-01 16:02:00') [Minutes] 
    ,DATEDIFF(mi,'2011-01-01 07:55:00','2011-01-01 16:02:00')/60 [Hours] 
    --8 hours 
    ,DATEDIFF(mi,'2011-01-01 07:55:00','2011-01-01 16:02:00')%60 [Additional minute] 
    --7 minute 

但:

SELECT DATEDIFF(mi,'2011-01-01 08:00:59','2011-01-01 16:00:05') [Minutes] 
     --480 
     ,DATEDIFF(ss,'2011-01-01 08:00:59','2011-01-01 16:00:05')/60 [Seconds/60] 
     --479 

2)而不是使用DATEDIFF功能(带DATETIME[2][OFFSET]数据类型)的使用 - 运营商的DATETIME值:

DECLARE @Test TABLE 
(
    TestId INT IDENTITY(1,1) PRIMARY KEY 
    ,[Enter] DATETIME NOT NULL 
    ,[Exit] DATETIME NOT NULL 
); 
INSERT @Test 
VALUES ('2011-01-01 07:55:00','2011-01-01 16:02:02') 
     ,('2011-01-01 08:00:59','2011-01-01 16:00:05'); 

SELECT * 
     ,t.[Exit] - t.[Enter] AS MyDateDiff 
     ,DATEPART(hh,t.[Exit] - t.[Enter]) [Hours] 
     ,DATEPART(mi,t.[Exit] - t.[Enter]) [Additional minutes] 
     ,DATEPART(ss,t.[Exit] - t.[Enter]) [Additional seconds] 
FROM @Test t 

结果:

TestId  Enter     Exit     MyDateDiff    Hours  Additional minute Additional seconds 
----------- ----------------------- ----------------------- ----------------------- ----------- ----------------- ------------------ 
1   2011-01-01 07:55:00.000 2011-01-01 16:02:02.000 1900-01-01 08:07:02.000 8   7     2 
2   2011-01-01 08:00:59.000 2011-01-01 16:00:05.000 1900-01-01 07:59:06.000 7   59    6