SQL - вычислить сумму часов с использованием накопительного пакета - PullRequest
0 голосов
/ 04 декабря 2018

Я хочу получить сумму всех часов в виде итога в последнем ряду.Я использую следующий запрос для получения результата:

create table time_test (type varchar(10),time varchar(10))
insert into time_test values ('A','01:25')
insert into time_test values ('B','02:30')
insert into time_test values ('C','05:56')
insert into time_test values ('D','00:50')

--select * from time_test

SELECT
  type = ISNULL(type, 'Total'),
  time = substring((cast(sum(((cast(substring (time,2,1) as decimal)*60 + cast(substring (time,4,2) as decimal))/60)) as varchar(10))),1,2)+':' + cast((cast((round(((cast((((cast((substring((cast((sum(((cast(substring (time,2,1) as decimal)*60 + cast(substring (time,4,2) as decimal))/60))) as varchar(10))),4,2)) as int))*60)) as decimal)/100)),0)) as int)) as varchar(10))
FROM time_test
GROUP BY ROLLUP(type);

ВЫХОД:

enter image description here

Как видите, время не наступаетПравильно, кроме этого общего расчета работает нормально.

Проблема: Пожалуйста, дайте мне знать, где я работаю неправильно при отображении данных.

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

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

У меня было похожее требование, и я решил его следующим образом:

select type, RTRIM(time/60) + ':' + RIGHT('0' + RTRIM(time%60),2) from
( 
    select type= ISNULL(type, 'Total'),
      time= SUM(DATEDIFF(MINUTE, '0:00:00', time))
    from time_test
    GROUP BY ROLLUP(type)
) x

Я считаю, что это более понятно и легче отследить

type    time
A       1:25
B       2:30
C       5:56
D       0:50
Total   10:41

Редактировать: Обновлен запросдля hour can be more then 24 hours

select type, RTRIM(time/60) + ':' + RIGHT('0' + RTRIM(time%60),2) from
( 
    select type= ISNULL(type, 'Total'),
      time= SUM(DATEDIFF(MINUTE, '0:00:00', 
        DATEADD(day, SUBSTRING(time,0,CHARINDEX(':',time,0)) / 24,
        DATEADD(hour, SUBSTRING(time,0,CHARINDEX(':',time,0)) % 24, 
        DATEADD(minute,SUBSTRING(time,CHARINDEX(':',time)+1,LEN(time)) +0, 0)) )))
    from time_test
    GROUP BY ROLLUP(type)
) x

Пример результата:

A       1:25
B       2:30
C       5:56
D       70:50
Total   80:41
0 голосов
/ 04 декабря 2018

Хорошо, так что быстрый просмотр кода, старайтесь избегать использования типа данных VARCHAR для хранения даты и / или времени.

ниже я сделал то, что сделал:

create table time_test (type varchar(10),time1 time)
insert into time_test values ('A','00:01:30')
insert into time_test values ('B','00:02:30')
insert into time_test values ('C','00:01:00')
insert into time_test values ('D','00:02:30')

SELECT
  type = ISNULL(type, 'Total'),
  seconds_worked = SUM(DATEDIFF(SECOND, '00:00', time1))
  FROM time_test
GROUP BY ROLLUP(type);

вы увидите Итог прибываетдо 450, что, если вы рассчитываете вручную из предоставленных данных, кажется правильным, то есть общее время составляет 450 секунд.

Вы можете использовать приведенную ниже формулу для возврата вашего времени в минутах и ​​секундах:

RTRIM(**450**/60) + ':' + RIGHT('0' + RTRIM(**450**%60),2)
0 голосов
/ 04 декабря 2018

Я бы сначала исправил ваш тип данных, время должно быть сохранено как time, а не varchar.Затем, как только вы исправите свой тип данных, вы можете обрабатывать ваши данные как то, что есть (время).

USE Sandbox;
GO

CREATE TABLE dbo.time_test ([type] varchar(10),
                            [time] time);
INSERT INTO dbo.time_test
VALUES ('A', '01:25'); --Assumes hh:mm
INSERT INTO dbo.time_test
VALUES ('B', '02:30');
INSERT INTO dbo.time_test
VALUES ('C', '05:56');
INSERT INTO dbo.time_test
VALUES ('D', '00:50');
GO

SELECT ISNULL([type],'Total') AS [Type],
       DATEADD(MINUTE,SUM(DATEDIFF(MINUTE,'00:00',[time])),CONVERT(time(0),'00:00')) AS [Time]
FROM dbo.time_test
GROUP BY [type] WITH ROLLUP;

GO

DROP TABLE dbo.time_test;

Это возвращает:

Type       Time
---------- ----------------
A          01:25:00
B          02:30:00
C          05:56:00
D          00:50:00
Total      10:41:00
...