使用断开间隔计算最小和最大时间SQL Server

时间:2019-06-14 22:56:45

标签: sql-server tsql date datetime

我需要计算两个日期之间的时间;问题是我有两行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因为剩余时间是由

所以最终结果将是:

第一行+第二行A +第二行= 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年5月6日: minLogin = 2019-06-05 21:59:00.000 maxLogout = 2019-06-06 06:00:00.000

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

2019年6月7日: minLogin = 2019-06-07 21:59:00.000 maxLogout = 2019-06-08 06:00:00.000

1 个答案:

答案 0 :(得分:0)

以下代码演示了如何使用通用表表达式(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;