【问题标题】:select punctuality report with sql用sql选择准时报告
【发布时间】:2015-02-16 13:28:24
【问题描述】:

我有 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.tbl 分支

+---------------+----------+-------------------+
| 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        |
+-------------------+---------------+-----------+-----------+----------+-----------+----------+-----------+-----------+------------+-------------+--------------+------------+-------------+----------+-----------+------------+-------------+

我想创建一份守时报告,在其中我们显示员工、分支机构、准时、计划时间以及员工迟到、早到或准时。

  • 员工同一天会有多个 IN。所以需要先 IN。
  • 需要每天获取详细信息,在两个日期之间,按 EmployeeId 分组
  • 需要根据分支和访问日期从 tblBranchTimingEntry 中选择调度时间。 IE。如果是星期日,则取 SundayIn,否则如果是星期一,则取 MondayIn,依此类推。
  • 对于不同日期范围的分支机构,也会有不同的时间表。例如:在一个月的前 15 天,一个分支机构有一个时间表,接下来的 15 天有另一个时间表。
  • 所以当我们取一个月的报告时,我们必须从 tblBranchTimingEntry 中选择 accessDate 介于 FromDate 和 ToDate 之间的调度时间
  • 因此,在前 15 天,计划时间将从 SundayIn 或 MondayIn 等开始......这介于该日期范围和下一个日期范围之后的 15 天之间。

我的逻辑是这样的

  1. 我们从 tblAccess 中选择员工一天中的第一个 IN 时间
  2. 根据分支,我们从tblBranch中选择BranchEntryId
  3. 并从 tblBranchTimingEntry 中选择与 BranchEntryId 匹配的行 和 AccessTime from tblAccess 之间的 fromDate 和 toDate 来自 tblBranchTimingEntry。
  4. 并选择对应星期几的列,即。 SundayIn 表示周日,以此类推。
  5. 然后我们计算时间方差,(ScheduleTime - InTime)。如果方差> 0,那么晚了那么多方差。如果它等于 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 |
+-------------+-------------------+---------+-----------+---------+--------------+---------------------+

到目前为止我做了什么?

我有这个问题。 (实际上查询是从here@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

这里我不知道如何将访问日期与从日期和从 tblBranchTimingEntry 中的日期进行比较。所以我在查询中选择了 ScheduleTime 和 TimeVariance 中的 TOP 1 结果。否则子查询返回多行。

还有其他方法可以做到这一点吗?或者我如何从 tblBranchTimingEntry 获取记录,其中访问日期在 fromdate 和 todate 之间。

谢谢


编辑

由于没有其他更好的答案,我自己回答这个问题。

【问题讨论】:

    标签: sql sql-server common-table-expression


    【解决方案1】:

    我认为您的查询太复杂了。这基本上应该是用一些奇特的逻辑连接三个表。

    这个结果查询并不是那么简单,因为您需要以下逻辑:

    • 每天为员工获取第一次访问权限
    • 比较员工输入的实际日期时间与预期时间
    • 做很多日期算术

    但是,这不需要额外的子查询。像这样的:

    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
    

    【讨论】:

    • 一个员工一天会有这么多的进出。所以我们要选择一天的第一个IN时间,得到sundayIN或mondayIN或tuesdayIN等对应的调度时间。
    【解决方案2】:

    我处理了我的查询并想出了一个解决方案。 由于没有其他更好的答案,我自己来回答这个问题。

    这就是我所做的。

    ;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]
    

    由此我得到了所需的输出。

    【讨论】:

      猜你喜欢
      • 2017-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      相关资源
      最近更新 更多