Рассчитать минимальное и максимальное время с интервалами отключения SQL Server - PullRequest
0 голосов
/ 15 июня 2019

Мне нужно рассчитать время между двумя датами; проблема в том, что у меня есть данные x-person в двух строках, начиная с дня 1 в момент времени x и заканчивая днем ​​2 в момент времени x, и снова начинаю день 2 во время x до дня 3 в момент времени x ...

Итак, мне нужно определить продолжительность каждого человека в день.

Надеюсь, вы, ребята, можете мне помочь !!!

Заранее спасибо.

Я пробовал некоторые варианты, но не могу получить нужный результат.

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

UPDATE:

Ответ не сработал для того, что мне нужно сделать, но я знаю, что вопрос немного сложен (извините, мой английский не очень хорош), я попытаюсь объяснить лучше, поэтому здесь я иду:

У меня есть данные для входа в систему и выхода из системы операторов колл-центра, эти агенты имеют рабочую смену с 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

1 Ответ

0 голосов
/ 15 июня 2019

Следующий код демонстрирует, как использовать общее табличное выражение (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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...