Отчет о времени с использованием времени начала и окончания - PullRequest
0 голосов
/ 01 мая 2019

Можно ли создать отчет с суммой часов за день, сгруппированный по идентификатору, с использованием отметки времени начала и окончания?

Мне нужно иметь возможность разделять время, охватывающее дни, и принимать часть этого времени и суммировать для правильной группы дат.

ПРИМЕЧАНИЕ. Идентификаторы даты относятся к таблице измерения даты.

------------------------------------------------------------------------------
TaskId   | StartDateId | EndDateId | StartTime           | EndTime 
------------------------------------------------------------------------------
2        | 20190317    | 20190318  | 2019-03-17 16:30:00 | 2019-03-18 09:00:00
------------------------------------------------------------------------------
1        | 20190318    | 20190318  | 2019-03-18 09:00:00 | 2019-03-18 16:30:00
------------------------------------------------------------------------------
2        | 20190318    | 20190319  | 2019-03-18 16:30:00 | 2019-03-19 09:00:00
------------------------------------------------------------------------------

Таким образом, исходя из этого, желаемый вывод отчета будет:

-------------------------
Date       | Task | Hours
-------------------------
2019-03-17 | 2    | 7.5
-------------------------
2019-03-18 | 1    | 7.5
-------------------------
2019-03-18 | 2    | 16.5
-------------------------
...

Единственное работающее решение, которое мне удалось реализовать, - это разделение записей, чтобы ни одна запись не охватывала несколько дней. Я надеялся найти решение для запроса отчета, а не решение на основе ETL.

Ответы [ 2 ]

1 голос
/ 01 мая 2019

Я попытался смоделировать вашу проблему здесь: https://rextester.com/DEV45608, и я надеюсь, что это поможет вам :) (CTD GetDates можно заменить на измерение вашей даты)

DECLARE @minDate DATE  
DECLARE @maxDate DATE  

CREATE TABLE Tasktime
(
    Task_id INT,
    Start_time DATETIME,
    End_time DATETIME
);

INSERT INTO Tasktime VALUES
(2,'2019-03-17 16:30:00','2019-03-18 09:00:00'),
(1,'2019-03-18 09:00:00','2019-03-18 16:30:00'),
(2,'2019-03-18 16:30:00','2019-03-19 09:00:00');

SELECT @mindate = MIN(Start_time) FROM Tasktime;

SELECT @maxdate = MAX(End_time) FROM Tasktime;

;WITH GetDates AS  
(  
SELECT 1 AS counter, @minDate as Date   
UNION ALL  
SELECT counter + 1, DATEADD(day,counter,@minDate)  
from GetDates  
WHERE DATEADD(day, counter, @minDate) <= @maxDate  
)  
SELECT counter, Date INTO #tmp FROM GetDates;

SELECT
g.Date,
t.Task_id,
SUM(
CASE WHEN CAST(t.Start_time AS DATE) = CAST(t.End_time AS DATE) THEN
       DATEDIFF(second, t.Start_time, t.End_time) / 3600.0
     WHEN CAST(t.Start_time AS DATE) = g.Date THEN
       DATEDIFF(second, t.Start_time, CAST(DATEADD(day,1,g.Date) AS DATETIME)) / 3600.0
     WHEN CAST(t.End_time AS DATE) = g.Date THEN
       DATEDIFF(second, CAST(g.Date AS DATETIME), t.End_time) / 3600.0
     ELSE
       24.0
     END) AS hours_on_the_day_for_the_task
from 
#tmp g
INNER JOIN
Tasktime t
ON
g.Date BETWEEN CAST(t.Start_time AS DATE) AND CAST(t.End_time AS DATE)
GROUP BY g.Date, t.Task_id
0 голосов
/ 01 мая 2019

Желаемую дату можно присоединить к измерению даты и вернуть «календарную дату», и вы можете отобразить эту дату в отчете.

Что касается ЧАСОВ .. когда вы извлекаете свой набор данных в SQL, просто сделайте это .. это так просто, как:

 cast(datediff(MINUTE,'2019-03-18 16:30:00','2019-03-19 09:00:00') /60.0 as decimal(13,1)) as 'Hours'

Так что в вашем случае это будет

 cast(datediff(MINUTE,sometable.startdate,sometable.enddate) /60.0 as decimal(13,1)) as 'Hours'

Простое выполнение ЧАСА вернет целый час ... а деление на 60 вернет целое число. Отсюда /60.0 и актерский состав

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...