【问题标题】:Calculate the min and max time with disconnection intervals SQL Server计算断开间隔 SQL Server 的最小和最大时间
【发布时间】:2019-06-14 22:56:45
【问题描述】:

我需要计算两个日期之间的时间;问题是我有两行 x 人的数据,从 x 时间的第 1 天开始,在 x 时间完成第 2 天,然后在 x 时间的第 2 天重新开始,直到 x 时间的第 3 天......

所以我需要确定每个人每天的持续时间。

希望大家能帮帮我!!!

提前谢谢你。

我已经尝试了一些选项,但无法获得我想要的结果。

-- Table example

DECLARE @tbl TABLE(person varchar(10), startDate DATE, startTime TIME(0), endDate DATE, endTime TIME(0))

INSERT INTO @tbl 
SELECT 'PERSON A' person, '2019-06-06' startDate, '02:14:00' startTime, '2019-06-06' endDate, '06:00:00' endTime

INSERT INTO @tbl 
SELECT 'PERSON A' person, '2019-06-06' startDate, '22:00:00' startTime, '2019-06-07' endDate, '06:00:00' endTime

SELECT * FROM  @tbl -- > This would be the table example

预期的结果是

First_Row = (2019-06-06 06:00:00 - 2019-06-06 02:14:00) => 03:46:00

Second_RowA = (2019-06-06 22:00:00 - 2019-06-06 24:00:00) => 02:00:00

Second_RowB = (2019-06-07 02:14:00 - 2019-06-07 00:00:00) => 02:14:00 因为剩余时间是由第一行计算的

所以最后的结果是:

First_Row + Second_RowA + SecondRowB = 08:00:00

更新:

答案对我需要做的事情不起作用,但我知道这个问题有点棘手(抱歉我的英语不好),我会尽力解释得更好,所以我开始了:

我有呼叫中心代理的登录和注销数据,这些代理的工作班次从 22 到 06,所以我需要计算的是 loginTime 的最小值和 logOutTime 的最大值,但这就是它变得复杂的地方,因为在某些情况下,代理在该时间范围内断开连接,然后在另一个班次开始的同一天在数据库中创建另一个登录事件,依此类推。

所以我的问题是:如何确定我需要的最小值和最大值,每个代理和每个日期只显示一次?

这是数据:

DECLARE @tbl TABLE(agentId VARCHAR(10), position VARCHAR(10), loginDate DATE, loginTime TIME(0), logoutDate DATE, logoutTime TIME(0))

INSERT INTO @tbl SELECT '311338', '230025', '2019-06-03', '21:59:00', '2019-06-04', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230025', '2019-06-04', '21:59:00', '2019-06-04', '23:30:00'
INSERT INTO @tbl SELECT '311338', '230025', '2019-06-04', '23:31:00', '2019-06-05', '06:01:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-05', '21:59:00', '2019-06-06', '02:13:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-06', '02:14:00', '2019-06-06', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230037', '2019-06-06', '22:00:00', '2019-06-07', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-07', '21:59:00', '2019-06-08', '00:53:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-08', '00:53:00', '2019-06-08', '06:00:00'
INSERT INTO @tbl SELECT '311338', '230038', '2019-06-09', '22:00:00', '2019-06-10', '06:09:00'

SELECT agentId
    ,position
    ,(CAST(loginDate AS DATETIME) + CAST(loginTime AS DATETIME)) loginTime
    ,(CAST(logoutDate AS DATETIME) + CAST(logoutTime AS DATETIME)) logoutTime
  FROM @tbl

agentId 311338 的结果是:

2019-05-06 日: minLogin = 2019-06-05 21:59:00.000 maxLogout = 2019-06-06 06:00:00.000

2019-06-06 日: minLogin = 2019-06-06 22:00:00.000 maxLogout = 2019-06-07 06:00:00.000

2019-06-07 日: minLogin = 2019-06-07 21:59:00.000 maxLogout = 2019-06-08 06:00:00.000

【问题讨论】:

    标签: sql-server tsql date datetime


    【解决方案1】:

    以下代码演示了如何使用公用表表达式 (CTE) 将日期和时间对转换为 DateTime 值、计算差异、汇总值并将结果转换为字符串。

    请注意,您的示例数据在第二行中的 endTime 不正确。

    您的问题有点不清楚,但您似乎只想要最终的总和。无需像您建议的那样将行分成每日间隔(Second_RowA 和 Second_RowB),您只需将差值求和即可。

    由于Time 被限制为小于 24 小时的值,我以秒为单位计算差异,对它们求和,然后将结果转换为小时数可能大于 24 的字符串。您可以将代码修改为如果你愿意,可以将结果格式化为“ddd hh:mm:ss”。

    在代码示例的末尾有几个select 语句被注释掉了。您可以将最终的select 替换为其他一个,以查看 CTE 的中间结果。

    DECLARE @tbl TABLE(person varchar(10), startDate DATE, startTime TIME(0), endDate DATE, endTime TIME(0))
    
    INSERT INTO @tbl 
    SELECT 'PERSON A' person, '2019-06-06' startDate, '02:14:00' startTime, '2019-06-06' endDate, '06:00:00' endTime
    
    INSERT INTO @tbl 
    SELECT 'PERSON A' person, '2019-06-06' startDate, '22:00:00' startTime, '2019-06-07' endDate, '02:14:00' endTime
    
    SELECT * FROM  @tbl;
    
    with
      DateTimes as ( -- Assemble the   Date   and   Time   into   DateTime    values.
        select Cast( StartDate as DateTime ) + Cast( StartTime as DateTime ) as StartDT,
          Cast( EndDate as DateTime ) + Cast( EndTime as DateTime ) as EndDT
          from @tbl ),
      DeltaTimes as ( -- Calculate the number of seconds between   StartDT   and   EndDT.
        select DateDiff( second, StartDT, EndDT ) as Seconds
          from DateTimes ),
      TotalTime as ( -- Sum all of the periods.
        select Sum( Seconds ) as TotalTime
          from DeltaTimes )
      -- You can replace the final   select   statement with one of these to display the intermediate results.
      --select * from DateTimes;
      --select * from DeltaTimes;
      --select * from TotalTime;
      select Cast( TotalTime / 3600 as VarChar(6) ) +
        ':' + Right( '0' + Cast( TotalTime / 60 % 60 as VarChar(2) ), 2 ) +
        ':' + Right( '0' + Cast( TotalTime % 60 as VarChar(2) ), 2 ) as TotalTime
        from TotalTime;
    

    【讨论】:

    • 好的,谢谢,你只是告诉我如何解决这个问题,另外......没有不正确的数据,实际上我从两个不同的来源获取信息,这就是你看到我的原因我试图限制第二行示例的结束时间,以更具体地说明我需要什么。
    • 我做了一些更改,因为问题不清楚。
    • @Steven (1) 您的更新应该是一个新问题,因为它与原始问题只有短暂的相似性。 (2) 您提供了样本数据,但未提供预期结果。然后添加了预期的结果,没有解释。 (3) 仍然没有意义。如果一个班次是从22:0006:00,那么21:5906:09 应该作为无效时间被丢弃。
    • 我无法丢弃这些时间,因为我需要它们来确定出勤 kpi,因此它们仍然是有效时间。我将发布一个新问题,感谢您的建议和您的时间来回答它是有帮助的。
    • 为此问题发布了一个新问题:stackoverflow.com/q/56650802/9829961
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多