我有一个指纹系统 它有几列 用户,设备,模式,活动时间
用户是员工 该设备是2个设备,一个是室外的外部人员,一个是室内的内部人员 包含多种模式的活动 F1:保留\。参加 F2:中断 F3:工作假 F4:个人休假 F5:吸烟休假
CREATE TABLE dbo.UserActivity (
[User] int NOT NULL,
Mode varchar(6) NOT NULL,
Activity varchar(6) NOT NULL,
ActivityTime datetime NOT NULL
)
GO
--Insert data into the UserActivity table
INSERT dbo.UserActivity ([User] ,Mode , Activity, ActivityTime)
VALUES (1,'F1' ,'Divout', CAST('2013-01-01 08:30' AS datetime))
, (1,'F3' ,'Divin', CAST('2013-01-01 10:45' AS datetime))
, (1,'F3' ,'Divout', CAST('2013-01-01 13:15' AS datetime))
, (1,'F5' ,'Divin', CAST('2013-01-01 15:30' AS datetime))
, (1,'F3' ,'Divin', CAST('2013-01-01 16:15' AS datetime))
, (1,'F3' ,'Divout', CAST('2013-01-01 17:00' AS datetime))
, (1,'F1' ,'Divout', CAST('2013-01-02 08:30' AS datetime))
, (1,'F3' ,'Divin', CAST('2013-01-02 10:45' AS datetime))
, (1,'F4' ,'Divout', CAST('2013-01-02 13:00' AS datetime))
, (1,'F1' ,'Divin', CAST('2013-01-02 16:45' AS datetime))
, (2,'F1' ,'Divout', CAST('2013-01-01 8:25' AS datetime))
, (2,'F3' ,'Divin', CAST('2013-01-01 11:30' AS datetime))
, (2,'F3' ,'Divout', CAST('2013-01-01 12:35' AS datetime))
, (2,'F1' ,'Divin', CAST('2013-01-01 14:45' AS datetime))
我很好地订购了每个人在开始和结束时的活动 我也处理了一些错误 1 - 如果相同的设备连续使用两次,那么它的错误“因为当你从里面打印时应该从外面打印” 2-如果启动活动与结束活动不匹配则错误“如果您打印F2模式然后返回则必须打印F2模式”
这是我的代码:
select *,Error_Column=CASE
WHEN ((Lag(T2.Activity, 1)OVER(ORDER BY T2.[UserName],T2.EndActivityTime,T2.CurrentMode)=T2.Activity)--2 finger prints from same device
or ((T2.PreviousMode<>T2.CurrentMode) and (T2.PreviousMode is not null or T2.CurrentMode is not Null)))--inside mode differenet than outside mode
then 1
else 0
end
from (
SELECT Activity --Device Place
,CurrentMode=Mode --Device Mode
, PreviousMode = --Inter F
CASE
WHEN Activity='Divout' --UserName was out and he return
THEN Lag([Mode], 1) OVER(ORDER BY [User],ActivityTime,Mode) --give me his last leave state
Else Null --Else UserName using inside so we don't need his last leave state
End
, ActivityDate = CAST(ActivityTime As DATE) --Date of Activity
, UserName = [User] --UserName
, EndActivityTime = ActivityTime
, StartActivityTime =
CASE
WHEN Activity='Divout' --UserName was out and he return
THEN Lag(ActivityTime, 1) OVER(ORDER BY [User], ActivityTime,Mode)
Else Null
End
, EndActivityDate = CAST(ActivityTime AS DATE)
, StartActivityDate =
CASE
WHEN Activity='Divout' --UserName was out and he return
Then CAST(Lag(ActivityTime, 1) OVER(ORDER BY [User], ActivityTime ,Mode) AS DATE)
Else Null
End
FROM dbo.UserActivity
where mode<>'F1'
Union
SELECT Activity --Device Place
,CurrentMode=Mode --Device Mode
, PreviousMode = --Inter F
CASE
WHEN Activity='Divin' --End of the Day
THEN Lag([Mode], 1) OVER(ORDER BY [User],ActivityTime,Mode) --give me his Attendance Mode
Else Null --Else UserName using outside so we don't need his last leave state
End
, ActivityDate = CAST(ActivityTime As DATE) --Date of Activity
, UserName = [User] --UserName
, EndActivityTime = ActivityTime
, StartActivityTime =
CASE
WHEN Activity='Divin'
THEN Lag(ActivityTime, 1) OVER(ORDER BY [User], ActivityTime,Mode)
Else Null
End
, EndActivityDate = CAST(ActivityTime AS DATE)
, StartActivityDate =
CASE
WHEN Activity='Divin'
Then CAST(Lag(ActivityTime, 1) OVER(ORDER BY [User], ActivityTime,Mode) AS DATE)
Else Null
End
FROM (select * from dbo.UserActivity where mode='F1') T1)T2
ORDER BY T2.[UserName],T2.EndActivityTime,T2.CurrentMode
我遇到的问题是有一些特殊情况我无法找到处理方法 例如。当你是“F3:工作假”时......你可能不会重返工作岗位 在这种情况下,F1将被F3关闭..也有时您可能会在工作日结束前用1小时休假。所以你会打印F4 在这种情况下,F1将被F4关闭。
我想了很多我应该如何处理我的代码中的这两个案例,但我无法找到解决方案
任何人都可以帮我处理它们...... 提前谢谢答案 0 :(得分:0)
我建议您在逻辑中使用 PARTITION BY 。例如:
select * from ( select CAST(ActivityTime AS date) act_date , row_number() over(partition by [User], CAST(ActivityTime AS date) order by ActivityTime ASC) start_row , row_number() over(partition by [User], CAST(ActivityTime AS date) order by ActivityTime DESC) end_row , [User] , Mode , Activity , ActivityTime from UserActivity ) d order by act_date, [User], start_row ;
在start_row 1和end_row 1之间,您可以看到每个用户每天的完整活动顺序。我认为,一旦建立了这些边界,它将使您更容易应用业务逻辑。
act_date | start_row | end_row | User | Mode | Activity | ActivityTime :----------|-----------|-------- | -----|------|----------|-------------------- 01/01/2013 | 1 | 6 | 1 | F1 | Divout | 01/01/2013 08:30:00 01/01/2013 | 2 | 5 | 1 | F3 | Divin | 01/01/2013 10:45:00 01/01/2013 | 3 | 4 | 1 | F3 | Divout | 01/01/2013 13:15:00 01/01/2013 | 4 | 3 | 1 | F5 | Divin | 01/01/2013 15:30:00 01/01/2013 | 5 | 2 | 1 | F3 | Divin | 01/01/2013 16:15:00 01/01/2013 | 6 | 1 | 1 | F3 | Divout | 01/01/2013 17:00:00 01/01/2013 | 1 | 4 | 2 | F1 | Divout | 01/01/2013 08:25:00 01/01/2013 | 2 | 3 | 2 | F3 | Divin | 01/01/2013 11:30:00 01/01/2013 | 3 | 2 | 2 | F3 | Divout | 01/01/2013 12:35:00 01/01/2013 | 4 | 1 | 2 | F1 | Divin | 01/01/2013 14:45:00 02/01/2013 | 1 | 4 | 1 | F1 | Divout | 02/01/2013 08:30:00 02/01/2013 | 2 | 3 | 1 | F3 | Divin | 02/01/2013 10:45:00 02/01/2013 | 3 | 2 | 1 | F4 | Divout | 02/01/2013 13:00:00 02/01/2013 | 4 | 1 | 1 | F1 | Divin | 02/01/2013 16:45:00
dbfiddle here