select 准时报告 sql
select punctuality report with sql
我有 3 张桌子。
1.tblAccess
+------------+--------------+----------+-----------------+------------+-------+
| EmployeeId | EmployeeName | Location | AccessTime | ReaderType |Branch |
+------------+--------------+----------+-----------------+------------+-------+
| _1346 | A | L1 | 7/11/2014 10:00 | IN |NBAD001|
| _1347 | B | L2 | 7/10/2014 10:58 | IN |NBAD001|
| _1346 | A | L3 | 7/11/2014 23:39 | OUT |NBAD001|
| _1347 | B | L4 | 7/10/2014 23:58 | OUT |NBAD001|
| _1364 | C | L5 | 7/11/2014 10:00 | IN |NBAD005|
| _1367 | D | L6 | 7/10/2014 10:58 | IN |NBAD002|
| _1367 | D | L7 | 7/10/2014 22:42 | OUT |NBAD002|
| _1364 | C | L8 | 7/11/2014 23:58 | OUT |NBAD005|
| _1422 | E | L9 | 7/11/2014 23:58 | IN |NBAD004|
| _1422 | E | L10 | 7/11/2014 23:10 | IN |NBAD004|
| _1111 | F | L20 | 7/10/2014 23:10 | OUT |NBAD003|
+------------+--------------+----------+-----------------+------------+-------+
2.tblBranch
+---------------+----------+-------------------+
| BranchEntryId | BranchID | BranchName |
+---------------+----------+-------------------+
| 24 | NBAD001 | Motor City Branch |
| 25 | NBAD002 | B2 |
| 26 | NBAD003 | B3 |
| 27 | NBAD004 | B4 |
| 28 | NBAD005 | B5 |
| 29 | NBAD006 | B6 |
| 30 | NBAD007 | B7 |
+---------------+----------+-------------------+
3.tblBranchTimingEntry
+-------------------+---------------+-----------+-----------+----------+-----------+----------+-----------+-----------+------------+-------------+--------------+------------+-------------+----------+-----------+------------+-------------+
| BranchTimeEntryID | BranchEntryID | fromDate | toDate | SundayIn | SundayOut | MondayIn | MondayOut | TuesdayIn | TuesdayOut | WednesdayIn | WednesdayOut | ThursdayIn | ThursdayOut | FridayIn | FridayOut | SaturdayIn | SaturdayOut |
+-------------------+---------------+-----------+-----------+----------+-----------+----------+-----------+-----------+------------+-------------+--------------+------------+-------------+----------+-----------+------------+-------------+
| 1 | 24 | 7/10/2014 | 7/30/2014 | 0:00 | 0:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 9:30 | 15:30 | 9:30 | 15:30 |
| 2 | 24 | 7/1/2014 | 7/9/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 3 | 25 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 4 | 26 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 5 | 27 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 6 | 28 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 7 | 29 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 8 | 30 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
+-------------------+---------------+-----------+-----------+----------+-----------+----------+-----------+-----------+------------+-------------+--------------+------------+-------------+----------+-----------+------------+-------------+
我想创建一个准时报告,其中我们显示员工、分支机构、准时、计划时间和 emp 是迟到或早到或准时。
- 同一天会有多个IN因为employees.So需要先IN。
- 需要按天获取详细信息,在两个日期之间,按 EmployeeId 分组
- 需要select根据分支和访问日期从tblBranchTimingEntry 调度时间。 IE。如果是星期天,则取 SundayIn,如果是星期一,则取 MondayIn,依此类推。
- 另外,不同日期范围的分行会有不同的时间表。例如:对于一个分支机构,一个月的前 15 天他们有一个时间表,而接下来的 15 天则有另一个时间表。
- 因此,当我们获取一个月的报告时,我们必须 select 安排访问日期介于 tblBranchTimingEntry
的 FromDate 和 ToDate 之间的时间
- 因此,对于前 15 天,计划时间将从 SundayIn 或 MondayIn 等开始......介于该日期范围和下一个日期范围的后 15 天之间。
我的逻辑是这样的
- 我们 select 一天中来自 tblAccess 的员工首次 IN 时间
- 根据分支,我们 select 来自 tblBranch
的 BranchEntryId
- 和 select 来自 tblBranchTimingEntry 的行与 BranchEntryId 匹配
和来自 tblBranchTimingEntry 的 fromDate 和 toDate 之间的 tblAccess 的 AccessTime。
- 和select列对应的星期几,即。 SundayIn 表示星期天,依此类推。
- 然后我们计算时间方差,(ScheduleTime - InTime)。如果方差 > 0,则延迟那么大的方差。如果它等于 0,则 emp 准时。如果它 < 0 ,则 emp 早于计划。
需要结果
+-------------+-------------------+---------+-----------+---------+--------------+---------------------+
| Employee ID | Name | Branch | Date | In Time | ScheduleTime | TimeVariance |
+-------------+-------------------+---------+-----------+---------+--------------+---------------------+
| _1487 | basement paking | NBAD001 | 10/7/2014 | 23:01 | 10:00 | Late By 13:01 hours |
| _1346 | CHARLEY BAOUAMINA | NBAD001 | 10/7/2014 | 23:05 | 10:00 | Late By 13:05 hours |
| _1268 | DANA AZZI | NBAD001 | 10/7/2014 | 23:51 | 10:00 | Late By 13:51 hours |
| _1585 | DANA AZZI | NBAD003 | 10/7/2014 | 23:48 | 0:00 | Late By 23:48 hours |
+-------------+-------------------+---------+-----------+---------+--------------+---------------------+
到目前为止我做了什么?
我有这个问题。 (实际上查询是根据我之前来自 by @wewesthemenace 的问题的答案修改的)
;WITH CTE AS(
SELECT
EmployeeID,
EmployeeName,
[Branch],
AccessDate = CAST(AccessTime AS DATE),
AccessTime = CAST(AccessTime AS TIME),
Location,
ReaderType,
In_RN = ROW_NUMBER() OVER(PARTITION BY EmployeeId, CAST(AccessTime AS DATE), ReaderType ORDER BY CAST(AccessTime AS TIME) ASC)
--Out_RN = ROW_NUMBER() OVER(PARTITION BY EmployeeId, CAST(AccessTime AS DATE), ReaderType ORDER BY CAST(AccessTime AS TIME) DESC)
FROM tblAccess
where CAST(AccessTime AS DATE) between '2014-07-10' and '2014-07-11'
AND ReaderType = 'IN'
)
SELECT
ROW_NUMBER() OVER (ORDER BY EmployeeID) AS [Sl No],
EmployeeID as[Employee ID],
EmployeeName as [Name],
[Branch],
[Date] = CONVERT(VARCHAR(10), AccessDate, 103),
[In Time] = ISNULL(SUBSTRING(CONVERT(VARCHAR(20), MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END)), 1, 5), '')
, ScheduleTime =
CASE DATENAME(DW,AccessDate)
WHEN 'Sunday' THEN (select TOP 1 (( SUBSTRING( convert(varchar, [SundayIn],108),1,5))) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Monday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [MondayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Tuesday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [TuesdayIn],108),1,5))) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Wednesday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [WednesdayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Thursday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [ThursdayIn],108),1,5))) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Friday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [FridayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Saturday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [SaturdayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
END
, TimeVariance =
CASE DATENAME(DW,AccessDate)
WHEN 'Sunday' THEN
(select TOP 1( case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Monday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Tuesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Wednesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Thursday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Friday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Saturday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
END
FROM CTE
WHERE In_RN = 1
GROUP BY EmployeeID, EmployeeName, AccessDate, [Branch]
ORDER BY EmployeeName, AccessDate
这里我不知道如何将访问日期与from date 和to date in from tblBranchTimingEntry 进行比较。所以我 select 查询中的 ScheduleTime 和 TimeVariance 中的 TOP 1 结果。否则子查询 return 多行。
还有其他方法吗?或者我如何从 tblBranchTimingEntry 获取记录,其中 accessdate 在 fromdate 和 todate 之间。
谢谢
编辑
由于没有其他更好的答案发布,我自己回答这个问题。
我觉得你的查询太复杂了。这基本上应该是用一些奇特的逻辑连接三个表。
这个结果查询并不那么简单,因为您需要逻辑来:
- 每天为员工获取第一个访问权限
- 将员工输入的实际日期时间与预期时间进行比较
- 做大量的日期运算
但是,这应该不需要额外的子查询。像这样:
select a.EmployeeId, a.Branch,
(case when cast(cast(accesstime as date) as datetime) + sundayin) < accesstime
then 'Late by '
else 'Early by '
end) +
(cast (case when DATENAME(DW, AccessDate) = 'Sunday'
then datediff(second, accesstime,
cast(cast(accesstime as date) as datetime) + sundayin)
when . . .
end) as varchar(255)) + ' seconds'
from (select a.*,
row_number() over (partition by employeeid, cast(accesstime as date) order by accesstime) as seqnum
from tblAccess a
where CAST(AccessTime AS DATE) between @DateFrom and @DateTo AND
ReaderType = 'IN'
) a join
tblBranch b
on a.branch = b.branchid and a.seqnum = 1 join
tblBranchTimingEntry bte
on b.BranchTimeEntryID = bte.BranchTimeEntryID
我处理了我的查询并想出了一个解决方案。
由于没有其他更好的答案发布,我自己回答这个问题。
这是我做的。
;WITH CTE AS(
select
EmployeeID,
EmployeeName,
[Branch],
[Date] = CAST(AccessTime AS DATE),
[InTime] = CAST(AccessTime AS TIME),
ReaderType,
In_RN = ROW_NUMBER() OVER(PARTITION BY EmployeeId, CAST(AccessTime AS DATE), ReaderType ORDER BY CAST(AccessTime AS TIME) ASC)
from
[dbo].[tblAccess] A
where a.ReaderType = 'IN'
and CAST(AccessTime AS DATE) between '2014-07-01' and '2014-07-30'
)
select
EmployeeID as[Employee ID],
EmployeeName as [Name],
[Branch],
[Date] = CONVERT(VARCHAR(10), [Date], 103),
[In Time] = ISNULL(SUBSTRING(CONVERT(VARCHAR(20), MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN [InTime] END)), 1, 5), ''),
CASE DATENAME(DW,[Date])
WHEN 'Sunday' THEN (select (SUBSTRING( convert(varchar, [SundayIn],108),1,5)) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Monday' THEN (select (SUBSTRING( convert(varchar, [MondayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Tuesday' THEN (select (SUBSTRING( convert(varchar, [TuesdayIn],108),1,5)) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Wednesday' THEN (select (SUBSTRING( convert(varchar, [WednesdayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Thursday' THEN (select (SUBSTRING( convert(varchar, [ThursdayIn],108),1,5)) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Friday' THEN (select (SUBSTRING( convert(varchar, [FridayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Saturday' THEN (select (SUBSTRING( convert(varchar, [SaturdayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
END as [ScheduledTime]
, TimeVariance =
CASE DATENAME(DW,[date])
WHEN 'Sunday' THEN
(select TOP 1( case
when cast(DATEDIFF(s,[InTime],[SundayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[SundayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Monday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[MondayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[MondayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Tuesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[TuesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[TuesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Wednesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[WednesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[WednesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Thursday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[ThursdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[ThursdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Friday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[FridayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[FridayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Saturday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[SaturdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[SaturdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
END
from CTE where In_RN = 1
GROUP BY EmployeeID, EmployeeName, [Date], [Branch], [InTime]
ORDER BY EmployeeName, [Date]
由此我得到了所需的输出。
我有 3 张桌子。
1.tblAccess
+------------+--------------+----------+-----------------+------------+-------+
| EmployeeId | EmployeeName | Location | AccessTime | ReaderType |Branch |
+------------+--------------+----------+-----------------+------------+-------+
| _1346 | A | L1 | 7/11/2014 10:00 | IN |NBAD001|
| _1347 | B | L2 | 7/10/2014 10:58 | IN |NBAD001|
| _1346 | A | L3 | 7/11/2014 23:39 | OUT |NBAD001|
| _1347 | B | L4 | 7/10/2014 23:58 | OUT |NBAD001|
| _1364 | C | L5 | 7/11/2014 10:00 | IN |NBAD005|
| _1367 | D | L6 | 7/10/2014 10:58 | IN |NBAD002|
| _1367 | D | L7 | 7/10/2014 22:42 | OUT |NBAD002|
| _1364 | C | L8 | 7/11/2014 23:58 | OUT |NBAD005|
| _1422 | E | L9 | 7/11/2014 23:58 | IN |NBAD004|
| _1422 | E | L10 | 7/11/2014 23:10 | IN |NBAD004|
| _1111 | F | L20 | 7/10/2014 23:10 | OUT |NBAD003|
+------------+--------------+----------+-----------------+------------+-------+
2.tblBranch
+---------------+----------+-------------------+
| BranchEntryId | BranchID | BranchName |
+---------------+----------+-------------------+
| 24 | NBAD001 | Motor City Branch |
| 25 | NBAD002 | B2 |
| 26 | NBAD003 | B3 |
| 27 | NBAD004 | B4 |
| 28 | NBAD005 | B5 |
| 29 | NBAD006 | B6 |
| 30 | NBAD007 | B7 |
+---------------+----------+-------------------+
3.tblBranchTimingEntry
+-------------------+---------------+-----------+-----------+----------+-----------+----------+-----------+-----------+------------+-------------+--------------+------------+-------------+----------+-----------+------------+-------------+
| BranchTimeEntryID | BranchEntryID | fromDate | toDate | SundayIn | SundayOut | MondayIn | MondayOut | TuesdayIn | TuesdayOut | WednesdayIn | WednesdayOut | ThursdayIn | ThursdayOut | FridayIn | FridayOut | SaturdayIn | SaturdayOut |
+-------------------+---------------+-----------+-----------+----------+-----------+----------+-----------+-----------+------------+-------------+--------------+------------+-------------+----------+-----------+------------+-------------+
| 1 | 24 | 7/10/2014 | 7/30/2014 | 0:00 | 0:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 9:30 | 15:30 | 9:30 | 15:30 |
| 2 | 24 | 7/1/2014 | 7/9/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 3 | 25 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 4 | 26 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 5 | 27 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 6 | 28 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 7 | 29 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
| 8 | 30 | 7/1/2014 | 7/30/2014 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 10:00 | 18:00 | 0:00 | 0:00 | 0:00 | 0:00 |
+-------------------+---------------+-----------+-----------+----------+-----------+----------+-----------+-----------+------------+-------------+--------------+------------+-------------+----------+-----------+------------+-------------+
我想创建一个准时报告,其中我们显示员工、分支机构、准时、计划时间和 emp 是迟到或早到或准时。
- 同一天会有多个IN因为employees.So需要先IN。
- 需要按天获取详细信息,在两个日期之间,按 EmployeeId 分组
- 需要select根据分支和访问日期从tblBranchTimingEntry 调度时间。 IE。如果是星期天,则取 SundayIn,如果是星期一,则取 MondayIn,依此类推。
- 另外,不同日期范围的分行会有不同的时间表。例如:对于一个分支机构,一个月的前 15 天他们有一个时间表,而接下来的 15 天则有另一个时间表。
- 因此,当我们获取一个月的报告时,我们必须 select 安排访问日期介于 tblBranchTimingEntry 的 FromDate 和 ToDate 之间的时间
- 因此,对于前 15 天,计划时间将从 SundayIn 或 MondayIn 等开始......介于该日期范围和下一个日期范围的后 15 天之间。
我的逻辑是这样的
- 我们 select 一天中来自 tblAccess 的员工首次 IN 时间
- 根据分支,我们 select 来自 tblBranch 的 BranchEntryId
- 和 select 来自 tblBranchTimingEntry 的行与 BranchEntryId 匹配 和来自 tblBranchTimingEntry 的 fromDate 和 toDate 之间的 tblAccess 的 AccessTime。
- 和select列对应的星期几,即。 SundayIn 表示星期天,依此类推。
- 然后我们计算时间方差,(ScheduleTime - InTime)。如果方差 > 0,则延迟那么大的方差。如果它等于 0,则 emp 准时。如果它 < 0 ,则 emp 早于计划。
需要结果
+-------------+-------------------+---------+-----------+---------+--------------+---------------------+
| Employee ID | Name | Branch | Date | In Time | ScheduleTime | TimeVariance |
+-------------+-------------------+---------+-----------+---------+--------------+---------------------+
| _1487 | basement paking | NBAD001 | 10/7/2014 | 23:01 | 10:00 | Late By 13:01 hours |
| _1346 | CHARLEY BAOUAMINA | NBAD001 | 10/7/2014 | 23:05 | 10:00 | Late By 13:05 hours |
| _1268 | DANA AZZI | NBAD001 | 10/7/2014 | 23:51 | 10:00 | Late By 13:51 hours |
| _1585 | DANA AZZI | NBAD003 | 10/7/2014 | 23:48 | 0:00 | Late By 23:48 hours |
+-------------+-------------------+---------+-----------+---------+--------------+---------------------+
到目前为止我做了什么?
我有这个问题。 (实际上查询是根据我之前来自
;WITH CTE AS(
SELECT
EmployeeID,
EmployeeName,
[Branch],
AccessDate = CAST(AccessTime AS DATE),
AccessTime = CAST(AccessTime AS TIME),
Location,
ReaderType,
In_RN = ROW_NUMBER() OVER(PARTITION BY EmployeeId, CAST(AccessTime AS DATE), ReaderType ORDER BY CAST(AccessTime AS TIME) ASC)
--Out_RN = ROW_NUMBER() OVER(PARTITION BY EmployeeId, CAST(AccessTime AS DATE), ReaderType ORDER BY CAST(AccessTime AS TIME) DESC)
FROM tblAccess
where CAST(AccessTime AS DATE) between '2014-07-10' and '2014-07-11'
AND ReaderType = 'IN'
)
SELECT
ROW_NUMBER() OVER (ORDER BY EmployeeID) AS [Sl No],
EmployeeID as[Employee ID],
EmployeeName as [Name],
[Branch],
[Date] = CONVERT(VARCHAR(10), AccessDate, 103),
[In Time] = ISNULL(SUBSTRING(CONVERT(VARCHAR(20), MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END)), 1, 5), '')
, ScheduleTime =
CASE DATENAME(DW,AccessDate)
WHEN 'Sunday' THEN (select TOP 1 (( SUBSTRING( convert(varchar, [SundayIn],108),1,5))) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Monday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [MondayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Tuesday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [TuesdayIn],108),1,5))) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Wednesday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [WednesdayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Thursday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [ThursdayIn],108),1,5))) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Friday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [FridayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Saturday' THEN (select TOP 1 ((SUBSTRING( convert(varchar, [SaturdayIn],108),1,5) )) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
END
, TimeVariance =
CASE DATENAME(DW,AccessDate)
WHEN 'Sunday' THEN
(select TOP 1( case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SundayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Monday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[MondayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Tuesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[TuesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Wednesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[WednesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Thursday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[ThursdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Friday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[FridayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
WHEN 'Saturday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,ISNULL(MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN AccessTime END), null),[SaturdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]))
END
FROM CTE
WHERE In_RN = 1
GROUP BY EmployeeID, EmployeeName, AccessDate, [Branch]
ORDER BY EmployeeName, AccessDate
这里我不知道如何将访问日期与from date 和to date in from tblBranchTimingEntry 进行比较。所以我 select 查询中的 ScheduleTime 和 TimeVariance 中的 TOP 1 结果。否则子查询 return 多行。
还有其他方法吗?或者我如何从 tblBranchTimingEntry 获取记录,其中 accessdate 在 fromdate 和 todate 之间。
谢谢
编辑
由于没有其他更好的答案发布,我自己回答这个问题。
我觉得你的查询太复杂了。这基本上应该是用一些奇特的逻辑连接三个表。
这个结果查询并不那么简单,因为您需要逻辑来:
- 每天为员工获取第一个访问权限
- 将员工输入的实际日期时间与预期时间进行比较
- 做大量的日期运算
但是,这应该不需要额外的子查询。像这样:
select a.EmployeeId, a.Branch,
(case when cast(cast(accesstime as date) as datetime) + sundayin) < accesstime
then 'Late by '
else 'Early by '
end) +
(cast (case when DATENAME(DW, AccessDate) = 'Sunday'
then datediff(second, accesstime,
cast(cast(accesstime as date) as datetime) + sundayin)
when . . .
end) as varchar(255)) + ' seconds'
from (select a.*,
row_number() over (partition by employeeid, cast(accesstime as date) order by accesstime) as seqnum
from tblAccess a
where CAST(AccessTime AS DATE) between @DateFrom and @DateTo AND
ReaderType = 'IN'
) a join
tblBranch b
on a.branch = b.branchid and a.seqnum = 1 join
tblBranchTimingEntry bte
on b.BranchTimeEntryID = bte.BranchTimeEntryID
我处理了我的查询并想出了一个解决方案。 由于没有其他更好的答案发布,我自己回答这个问题。
这是我做的。
;WITH CTE AS(
select
EmployeeID,
EmployeeName,
[Branch],
[Date] = CAST(AccessTime AS DATE),
[InTime] = CAST(AccessTime AS TIME),
ReaderType,
In_RN = ROW_NUMBER() OVER(PARTITION BY EmployeeId, CAST(AccessTime AS DATE), ReaderType ORDER BY CAST(AccessTime AS TIME) ASC)
from
[dbo].[tblAccess] A
where a.ReaderType = 'IN'
and CAST(AccessTime AS DATE) between '2014-07-01' and '2014-07-30'
)
select
EmployeeID as[Employee ID],
EmployeeName as [Name],
[Branch],
[Date] = CONVERT(VARCHAR(10), [Date], 103),
[In Time] = ISNULL(SUBSTRING(CONVERT(VARCHAR(20), MAX(CASE WHEN ReaderType = 'IN' AND In_RN = 1 THEN [InTime] END)), 1, 5), ''),
CASE DATENAME(DW,[Date])
WHEN 'Sunday' THEN (select (SUBSTRING( convert(varchar, [SundayIn],108),1,5)) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Monday' THEN (select (SUBSTRING( convert(varchar, [MondayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Tuesday' THEN (select (SUBSTRING( convert(varchar, [TuesdayIn],108),1,5)) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Wednesday' THEN (select (SUBSTRING( convert(varchar, [WednesdayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Thursday' THEN (select (SUBSTRING( convert(varchar, [ThursdayIn],108),1,5)) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Friday' THEN (select (SUBSTRING( convert(varchar, [FridayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Saturday' THEN (select (SUBSTRING( convert(varchar, [SaturdayIn],108),1,5) ) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
END as [ScheduledTime]
, TimeVariance =
CASE DATENAME(DW,[date])
WHEN 'Sunday' THEN
(select TOP 1( case
when cast(DATEDIFF(s,[InTime],[SundayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[SundayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SundayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Monday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[MondayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[MondayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[MondayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Tuesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[TuesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[TuesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[TuesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Wednesday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[WednesdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[WednesdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[WednesdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Thursday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[ThursdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[ThursdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[ThursdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Friday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[FridayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[FridayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[FridayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
WHEN 'Saturday' THEN
(select TOP 1(case
when cast(DATEDIFF(s,[InTime],[SaturdayIn]) as float) < 0 then 'Late By '+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))%3600/60 as varchar(10))+ ' hours'
when cast(DATEDIFF(s,[InTime],[SaturdayIn]) as float) = 0 then 'On Time'
else 'Early By '+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))/3600 as varchar(10))+ ':'+ cast(ABS(DATEDIFF(S,[InTime],[SaturdayIn]))%3600/60 as varchar(10))+ ' hours' end) from [dbo].[tblBranchTimingEntry] where BranchEntryID= (select [BranchEntryId] from [dbo].[tblBranch] where [BranchID]= [Branch]) and [Date] between fromDate and toDate)
END
from CTE where In_RN = 1
GROUP BY EmployeeID, EmployeeName, [Date], [Branch], [InTime]
ORDER BY EmployeeName, [Date]
由此我得到了所需的输出。