Агрегирование (группирование) по 15-секундным интервалам // Microsoft SQL Server 2019 - PullRequest
0 голосов
/ 13 апреля 2020

Я новичок в Microsoft SQL Server 2019. В настоящее время я пытаюсь агрегировать Timestamp (тип datetime) с интервалом в 15 секунд.

Желаемый результат:

Timestamp               Timestamp2
2019-01-01 04:00:00.487 2019-01-01 04:00:15.000
2019-01-01 04:00:01.487 2019-01-01 04:00:15.000
2019-01-01 04:00:02.487 2019-01-01 04:00:15.000
2019-01-01 04:00:03.487 2019-01-01 04:00:15.000
2019-01-01 04:00:04.487 2019-01-01 04:00:15.000
2019-01-01 04:00:05.487 2019-01-01 04:00:15.000
2019-01-01 04:00:06.487 2019-01-01 04:00:15.000
2019-01-01 04:00:07.487 2019-01-01 04:00:15.000
2019-01-01 04:00:08.487 2019-01-01 04:00:15.000
2019-01-01 04:00:09.487 2019-01-01 04:00:15.000
2019-01-01 04:00:10.487 2019-01-01 04:00:15.000
2019-01-01 04:00:11.487 2019-01-01 04:00:15.000
2019-01-01 04:00:12.487 2019-01-01 04:00:15.000
2019-01-01 04:00:13.487 2019-01-01 04:00:15.000
2019-01-01 04:00:14.487 2019-01-01 04:00:15.000
2019-01-01 04:00:15.487 2019-01-01 04:00:30.000
2019-01-01 04:00:16.487 2019-01-01 04:00:30.000
2019-01-01 04:00:17.487 2019-01-01 04:00:30.000
2019-01-01 04:00:18.487 2019-01-01 04:00:30.000
2019-01-01 04:00:19.487 2019-01-01 04:00:30.000

Я пытался преобразовать "1-минутный интервал" из

Select 
Timestamp, 
dateadd(MINUTE, 1+datediff(MINUTE, 0, [Timestamp]), 0) AS Timestamp2 
FROM tags.dbo.jan
where ValueID = '349' and Timestamp < '2019-01-01 04:02:00.000'

в

Select   
Timestamp, 
dateadd(second, 15+datediff(second, 0, [Timestamp]), 0) AS Timestamp2 
FROM tags.dbo.jan
where ValueID = '349' and Timestamp < '2019-01-01 04:02:00.000'

и столкнулся с проблемой

The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

Тогда Я пытался использовать datediff_big

Select   
Timestamp, 
dateadd(second, 15+datediff_big(second, 0, [Timestamp]), 0) AS Timestamp2 
FROM tags.dbo.jan
where ValueID = '349' and Timestamp < '2019-01-01 04:02:00.000'

и получил ошибку

Arithmetic overflow error converting expression to data type int.

Я пытался использовать

Select Timestamp,
       datetimefromparts(year(Timestamp), month(Timestamp), day(Timestamp),
                         datepart(hour, Timestamp),
                         datepart(minute, Timestamp),
                         (ceiling(datepart(second, Timestamp)) / 15) * 15,
                         0
                        ) as timestamp2
FROM jan.dbo.jan
where ValueID = '349' and
      Timestamp < '2019-01-01 04:02:00.000';

, но у меня есть эти результаты

2019-01-01 04:00:12.487 2019-01-01 04:00:00.000
2019-01-01 04:00:13.487 2019-01-01 04:00:00.000
2019-01-01 04:00:14.487 2019-01-01 04:00:00.000
2019-01-01 04:00:15.487 2019-01-01 04:00:15.000
2019-01-01 04:00:16.487 2019-01-01 04:00:15.000
2019-01-01 04:00:17.487 2019-01-01 04:00:15.000

вместо желаемого

2019-01-01 04:00:12.487 2019-01-01 04:00:15.000
2019-01-01 04:00:13.487 2019-01-01 04:00:15.000
2019-01-01 04:00:14.487 2019-01-01 04:00:15.000
2019-01-01 04:00:15.487 2019-01-01 04:00:30.000
2019-01-01 04:00:16.487 2019-01-01 04:00:30.000
2019-01-01 04:00:17.487 2019-01-01 04:00:30.000

Должен начинаться с первых 15 секунд группы

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Вы можете использовать datetimefromparts():

Select Timestamp,
       datetimefromparts(year(Timestamp), month(Timestamp), day(Timestamp),
                         datepart(hour, Timestamp),
                         datepart(minute, Timestamp),
                         (ceiling(datepart(second, Timestamp)) / 15) * 15,
                         0
                        ) as timestamp2
FROM tags.dbo.jan
where ValueID = '349' and
      Timestamp < '2019-01-01 04:02:00.000';
0 голосов
/ 13 апреля 2020
declare @t table(thetimestamp datetime);
insert into @t(thetimestamp) 
values('20190101 04:00:00.487'), ('20190101 04:00:02.487'),
('20190101 04:00:15.487'), ('20190101 04:00:20.487'),
('20190101 04:00:30.487'), ('20190101 04:00:35.487'),
('20190101 04:00:45.487'), ('20190101 04:00:57.487'), 
--
('20190101 04:00:00.000'), ('20190101 04:00:15.000'),  ('20190101 04:00:30.000'), ('20190101 04:00:45.000');

select *, 
    --add ms to next 15sec boundary
    dateadd(millisecond, 
    (15000-((1000*datepart(second, thetimestamp)+ datepart(millisecond, thetimestamp))%15000))%15000,
    thetimestamp) as upper15sec,
    --subtract ms from previous 15sec boundary
    dateadd(millisecond, 
    -(15000+((1000*datepart(second, thetimestamp)+ datepart(millisecond, thetimestamp))%15000))%15000,
    thetimestamp) as lower15sec
from @t;
...