它并不像创建N分钟长的时间间隔那么简单。一条记录可能是10:04,另一条记录是10:17,其中N是15。
也许用户功能可行,也许是CTE。它可能需要在同一源表上进行多次连接。
我正在寻找最优雅的#34;解。也许SQL中有一个功能,我不知道哪个让这很容易。
这是一个让答案更加一致的参考方案:
create table Comparisons (
DateField DateTime NOT NULL,
Amount int not null, -- default to 5
)
insert into Comparisons (DateField) values ('2000-01-01 10:04'),('2000-01-01 10:17'),
('2000-01-01 12:01'),('2000-01-01 11:54'),('2000-01-01 03:02'),('2000-01-01 03:05'),
('2000-01-01 05:02'),('2000-01-01 05:05'),('2000-01-01 05:19')
预期输出:
最后一个输出是可选的,但如果一个优雅的解决方案具有副作用,那么它是可以接受的。如果一个优雅的解决方案无法实现可选的最后输出,那么它就不会成为交易破坏者。
答案 0 :(得分:2)
我相信这会产生你想要的结果:
DECLARE @Comparisons TABLE (i DATETIME, amt INT NOT NULL DEFAULT(5));
INSERT @Comparisons (i) VALUES ('2016-01-01 10:04:00.000')
, ('2016-01-01 10:17:00.000')
, ('2016-01-01 10:25:00.000')
, ('2016-01-01 10:37:00.000')
, ('2016-01-01 10:44:00.000')
, ('2016-01-01 11:52:00.000')
, ('2016-01-01 11:59:00.000')
, ('2016-01-01 12:10:00.000')
, ('2016-01-01 12:22:00.000')
, ('2016-01-01 13:00:00.000')
, ('2016-01-01 09:00:00.000');
DECLARE @N INT = 15;
WITH T AS (
SELECT i
, amt
, CASE WHEN DATEDIFF(MINUTE, previ, i) <= @N THEN 0 ELSE 1 END RN1
, CASE WHEN DATEDIFF(MINUTE, i, nexti) > @N THEN 1 ELSE 0 END RN2
FROM @Comparisons t
OUTER APPLY (SELECT MAX(i) FROM @Comparisons WHERE i < t.i)x(previ)
OUTER APPLY (SELECT MIN(i) FROM @Comparisons WHERE i > t.i)y(nexti)
)
, T2 AS (
SELECT CASE RN1 WHEN 1 THEN i ELSE (SELECT MAX(i) FROM T WHERE RN1 = 1 AND i < T1.i) END mintime
, CASE WHEN RN2 = 1 THEN i ELSE ISNULL((SELECT MIN(i) FROM T WHERE RN2 = 1 AND i > T1.i), i) END maxtime
, amt
FROM T T1
)
SELECT mintime, maxtime, sum(amt) total
FROM T2
GROUP BY mintime, maxtime
ORDER BY mintime;
它可能比它可能有点笨拙,但它基本上只是在@ N分钟链中分组任何东西。
答案 1 :(得分:1)
您希望根据至少&lt; N&gt;之间的间隙对记录进行分组。分钟。
在SQL Server 2012+中,您可以使用lag()
来识别组的开始时间和累积总和来识别组:
select min(datefield), max(datefield), count(*) as num, sum(amount)
from (select c.*,
sum(case when prev_datefield < dateadd(minute, -N, datefield)
then 1 else 0
end) over (order by datefield) as grp
from (select c.*,
lag(datefield) over (order by datefield) as prev_datefield
from Comparisons c
) c
) c
group by grp;
在早期版本中,您可以使用相关子查询或apply
来获得相同的功能(尽管性能要差得多)。
答案 2 :(得分:0)
如果检查相邻间隔,则可以使用间隔。这需要将源表记录乘以3
的伪代码:
select *
from Comparisons C, {-1, 0, 1} M
group by (datediff(mi, C.DateField, 0) / N) + M
这种方法的问题是如何消除额外的结果。我怀疑这是一种愚蠢的方法,但其他人可能会看到它的价值。
更新:此方法不适用于第4预期输出[min:.. 05:02,max:.. 05:19,总和:15]