从 SQL Server 中的多个打卡或多个打卡中获取打卡和打卡时间

Posted

技术标签:

【中文标题】从 SQL Server 中的多个打卡或多个打卡中获取打卡和打卡时间【英文标题】:Get Clock In and clock out time from multiple clock in or multiple clock out in SQL Server 【发布时间】:2019-05-23 06:44:30 【问题描述】:

我正在使用 Web 应用程序来管理员工的上班/下班时间以及计划班次的映射。

注意 LogType 1 表示时钟输入,2 表示时钟输出。

我的登录表结构如下

UserId       LogDateTime             LogType

 5005    2019-05-20 21:35:48.490        1
 5005    2019-05-20 22:25:00.000        1
 5005    2019-05-21 06:48:00.000        2
 5005    2019-05-21 07:01:15.383        2

 5006    2019-05-20 21:25:25.470        1
 5006    2019-05-20 23:48:29.568        2
 5006    2019-05-21 00:07:05.056        1
 5006    2019-05-21 07:25:35.853        2

 5007   2019-05-20 23:33:35.017         1
 5007   2019-05-21 00:18:56.087         2
 5007   2019-05-21 09:01:23.577         2

我想以以下格式获取时钟输入和时钟输出并将其用于计划班次的映射

UserId      Date            ClockIn                    ClockOut
5005      2019-05-20     2019-05-20 21:35:48.490     2019-05-21 07:01:15.383
5006      2019-05-20     2019-05-20 21:25:25.470     2019-05-21 07:25:35.853
5007      2019-05-21     2019-05-20 23:33:35.017     2019-05-21 09:01:23.577 

任何人都可以为此共享查询。

【问题讨论】:

你可以有多个打卡没有打卡?为什么5006 没有在 2 个不同的日期报告?请用逻辑更新问题 您能否再解释一下Date 列的逻辑。 2019-05-20 for UserId 50052019-05-21 for UserId 5007 怎么样? 请在您的问题中提供更多详细信息,查看发布的答案并在需要时向其发布 cmets,或者删除您的问题。 【参考方案1】:

试试这个,<myTable>需要换成实际的表名:

SELECT 
    UserId,
    CONVERT(CHAR(10), LogDateTime, 126) AS Date,
    LogDateTime AS ClockIn,
    -- this sub query will by using WHERE clause, ORDER BY, TOP 1
    -- get the closest CheckOut time for the same user
    (
        SELECT TOP 1 LogDateTime 
        FROM <myTable> AS t2 
        WHERE t2.UserId = t1.UserId 
              AND t2.LogDateTime > t1.LogDateTime
              AND LogType = 2
        ORDER BY LogDateTime ASC
    )  AS ClockOut
FROM <myTable> AS t1 
WHERE LogType = 1
    -- this sub query is to limit the result to only the latest CheckIn times
    AND t1.LogDateTime IN
    (
        SELECT MAX(t3.LogDateTime)
        FROM <myTable> AS t3
        WHERE t3.UserId = t1.UserId
          AND LogType = 1
    ) 

希望对你有帮助!

【讨论】:

OP 也需要选择日期列,我们需要更多解释(如 Arulkumar 的评论),因为日期是 Min()5005Max()5007 好吧,我写了一个我认为用户可能想要的答案。查询非常复杂(它需要很复杂,但可以用其他方式编写)。此外查询可能没有很好的性能,但它应该是一个开始【参考方案2】:

我假设Date 列背后的逻辑正在考虑用户分配签入和签出的日期,如果用户仅分配签入或仅签出,则该记录将被忽略(在实际生活中,可能会发生用户忘记)

无论如何,您应该使用MIN()MAX()Group ByHaving 作为下一个

我认为我的代码更好,但至少我的代码满足了需求

演示:-

Create table #MyTempTable (UserId int , LogDateTime Datetime,LogType int)

Insert into #MyTempTable values (5005,'2019-05-20 21:35:48.490',1)
Insert into #MyTempTable values (5005,'2019-05-20 22:25:00.000',1)
Insert into #MyTempTable values (5005,'2019-05-21 06:48:00.000',2)
Insert into #MyTempTable values (5005,'2019-05-21 07:01:15.383',2)
Insert into #MyTempTable values (5006,'2019-05-20 21:25:25.470',1)
Insert into #MyTempTable values (5006,'2019-05-20 23:48:29.568',2)
Insert into #MyTempTable values (5006,'2019-05-21 00:07:05.056',1)
Insert into #MyTempTable values (5006,'2019-05-21 07:25:35.853',2)
Insert into #MyTempTable values (5007,'2019-05-20 23:33:35.017',1)
Insert into #MyTempTable values (5007,'2019-05-21 00:18:56.087', 2)
Insert into #MyTempTable values (5007,'2019-05-21 09:01:23.577',2)

select UserId,min(Date) Date ,min(ClockIn) ClockIn ,Max(ClockOut) ClockOut 
from (
    select UserId, Min(convert(date,LogDateTime)) Date, 
    Min(LogDateTime) ClockIn , Max(LogDateTime) ClockOut,LogType
    from #MyTempTable
    Group by UserId,LogType
    having count(convert(date,LogDateTime)) > 1
    )t
Group by UserId

Drop table #MyTempTable

结果:-

UserId  Date        ClockIn                 ClockOut
5005    2019-05-20  2019-05-20 21:35:48.490 2019-05-21 07:01:15.383
5006    2019-05-20  2019-05-20 21:25:25.470 2019-05-21 07:25:35.853
5007    2019-05-21  2019-05-21 00:18:56.087 2019-05-21 09:01:23.577

【讨论】:

由于某些原因,您的解决方案似乎不起作用。首先,您没有注意ClockInClockOut 的日期,因此结果将在ClockInClockOut 中具有不同的日期,这是不可接受的跨度> 冷静点兄弟,这是不可接受的谁?!我使用的数据演示不是虚拟数据,它是来自 OP 的输入,我重新缓存的结果与 OP 由于他/她的问题而寻找的结果相同。最后我写了一个我认为有帮助的答案。 也许对他有帮助,但对其他读者(他们正在寻找解决方案)没有帮助。

以上是关于从 SQL Server 中的多个打卡或多个打卡中获取打卡和打卡时间的主要内容,如果未能解决你的问题,请参考以下文章

请用sql实现查询出每个员工2019年10月份上班打卡次数,并按打卡次数从大到小排序卡次数从大到小排序?

#打卡不停更#FFH浅析Ability框架中Stage模型与FA模型的差异

用 sqlserver 怎样查询出 数据表里 某月上班连续打卡15天的人

SQL 统计每日上班打卡和下班打卡语句

如何从 SQL Server 读取 MS Access 数据库以更新一个或多个表列中的数据?

剑指Offer打卡42.连续子数组的最大和