【问题标题】:How to get Min Check in time and Max check out time from table?如何从表中获取最小入住时间和最大退房时间?
【发布时间】:2019-09-30 12:33:03
【问题描述】:

我有一个存储员工签入和签出的表格。现在数据存储在 2 个不同的列和 2 行中,如下所示。如果员工在2019-09-01 21:30:00 签到并在2019-09-02 08:45:00 签出,则显示总小时数为负数。

这是数据:

DROP TABLE TestAtte;
CREATE TABLE TestAtte(
    ID INT,
    TimeIn DATETIME,
    TimeOut DATETIME
);

INSERT INTO TestAtte VALUES(1, '2019-09-01 21:30:00', NULL);
INSERT INTO TestAtte VALUES(2, NULL, '2019-09-02 08:48:00');
INSERT INTO TestAtte VALUES(3, '2019-09-03 17:16:00', NULL);
INSERT INTO TestAtte VALUES(4, NULL, '2019-09-04 09:14:00');

我的查询是这样的

SELECT MIN(TimeIn) Checkin, MAX(Timeout) CheckOut
FROM dbo.TestAtte
GROUP BY CAST(COALESCE(TimeIn, Timeout) AS DATE)

数据应该是这样的

TimeIn                      TimeOut
2019-09-01 21:30:00.000     2019-09-02 08:48:00.000
2019-09-03 17:16:00.000     2019-09-04 09:14:00.000

【问题讨论】:

  • 如何判断连续记录属于同一员工?

标签: sql-server tsql datetime


【解决方案1】:

您可能可以为此使用LAG 函数:

WITH cte AS (
    SELECT LAG(TimeIn) OVER (ORDER BY COALESCE(TimeIn, TimeOut)) AS TimeIn2
         , TimeOut
    FROM TestAtte
)
SELECT TimeIn2, TimeOut
FROM cte
WHERE TimeOut IS NOT NULL

如果表包含多个员工的记录,您需要在 OVER 子句中添加 PARTITION BY EmployeeID。结果将包含 orphan TimeOut 记录的 TimeIn = NULL。

【讨论】:

    【解决方案2】:

    这使用外部应用来查找每次进入后的第一次退出。

    SELECT CheckIn.TimeIn, CheckOut.TimeOut
    FROM dbo.TestAtte AS CheckIn
    OUTER APPLY
    (
    SELECT TOP 1 TimeOut
    FROM dbo.TestAtte AS AllOut
    WHERE AllOut.TimeOut > CheckIn.TimeIn
    ORDER BY AllOut.TimeOut ASC
    ) AS CheckOut
    WHERE TimeIn IS NOT NULL
    

    【讨论】:

      猜你喜欢
      • 2016-09-05
      • 2016-05-26
      • 1970-01-01
      • 2015-04-20
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多