SQL Server совокупная сумма DATEDIFF в процентах - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь получить кумулятивную сумму DATEDIFF в процентах от некоторых базовых данных, которые у меня есть, вот небольшой снимок:

ID     IIn                       IOut
AB123  2015-11-06 15:24:44.057   2015-11-14 01:00:00.000
QA565  2015-10-27 20:12:19.753   2015-11-06 03:00:00.000
UN555  2015-12-29 06:29:23.417   2016-01-03 08:00:00.000
LG602  2015-08-07 16:52:13.573   2015-08-11 03:00:00.000

ETC ETC

Затем я использую DATEDIFF, чтобы получить количество дней:

SELECT ID, DATEDIFF(hour, IIn, IOut)/24.0 IDays
FROM TimeTable

Что дает мне:

ID     IDays
AB123  7.416666
QA565  9.291666
UN555  5.083333
LG602  3.458333

То, что я хочу, - это число ID 'S, разделенное на их IDay (округленное в меньшую сторону) с совокупным% от самого низкого IDay до самого высокого значения, например:

ID     IDays  IDaysPer
LG602  3      12.5
UN555  5      33.33
AB123  7      62.49
QA565  9      100

Ответы [ 3 ]

0 голосов
/ 07 ноября 2018

А вот и вы: выводите совпадения с вашим ...

        create table #TEMp
(ID VARCHAR(100)
,IIn datetime
,IOut datetime
)


insert into #temp(ID,IIn,IOut) values
('AB123','2015-11-06T15:24:44.057','2015-11-14T01:00:00.000'),
('QA565','2015-10-27T20:12:19.753','2015-11-06T03:00:00.000'),
('UN555','2015-12-29T06:29:23.417','2016-01-03T08:00:00.000'),
('LG602','2015-08-07T16:52:13.573','2015-08-11T03:00:00.000')

select ID,IDays AS Idays,ROUND(CAST(SUM(IDays) OVER(ORDER BY IDays) AS FLOAT)/CAST(SUM(IDays)OVER() AS FLOAT) * 100,2) AS IdaysPer
from
(
select *,ROUND(DATEDIFF(hour, IIn, IOut)/24,0) IDays
from #TEMP
)T

enter image description here

0 голосов
/ 07 ноября 2018

Считайте, что TimeTable уже имеет данные

WITH t1 (ID, IDays)
AS (
    SELECT ID, DATEDIFF(hour, IIn, IOut) / 24.0 AS IDays
    FROM TimeTable
)
SELECT 
    ID, FLOOR(IDays), 
    (FLOOR(IDays) / (SELECT SUM(FLOOR(IDays)) FROM t1 t2 WHERE t1.IDays <= t2.IDays)) * 100.0 AS IDaysPer
FROM t1
ORDER BY 2 ASC
0 голосов
/ 07 ноября 2018

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

declare @timeTable table (ID char(5) not null, IIn datetime not null,
                          IOut datetime not null)
insert into @timeTable(ID,IIn,IOut) values
('AB123','2015-11-06T15:24:44.057','2015-11-14T01:00:00.000'),
('QA565','2015-10-27T20:12:19.753','2015-11-06T03:00:00.000'),
('UN555','2015-12-29T06:29:23.417','2016-01-03T08:00:00.000'),
('LG602','2015-08-07T16:52:13.573','2015-08-11T03:00:00.000')

;With Diffs as (
    SELECT ID, DATEDIFF(hour, IIn, IOut)/24.0 IDays
    FROM @timeTable
)
select
    *,
    (
      SUM(IDays) OVER (ORDER BY IDays, ID)
      /
      SUM(IDays) OVER ()
    ) * 100 as IDaysPer
from
    Diffs
order by IDays

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

ID    IDays                                   IDaysPer
----- --------------------------------------- ---------------------------------------
LG602 3.458333                                13.696300
UN555 5.083333                                33.828300
AB123 7.416666                                63.201300
QA565 9.291666                                100.000000
...