You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server 15分钟时间窗口求列最值差的无循环T-SQL实现方案问询

完全可以实现,无需循环,使用时间分桶分组聚合的方案即可,仅需一次表扫描就能得到结果,性能远高于逐窗口循环查询的实现。

核心实现逻辑

先计算每条记录所属的15分钟时间窗口的唯一标识,相同标识的记录属于同一个时间窗口,直接按窗口标识+logicalId分组聚合即可得到每个窗口的统计结果。

方案1:基于unixTime毫秒字段实现(性能最优)

直接对数值类型的时间戳做计算,无需类型转换,性能最好:

DECLARE @startTimeInput BIGINT = 1636329609000; -- 替换为你实际的查询起始时间戳
DECLARE @endTimeInput BIGINT = 1636331379000; -- 替换为你实际的查询结束时间戳
DECLARE @windowMs BIGINT = 15 * 60 * 1000; -- 15分钟对应的毫秒数

-- 可直接查询,也可插入到临时表
INSERT INTO #energyDataTable (startTime, endTime, value, logicalId)
SELECT 
    MIN(ts.Timestamp) AS start_time,
    MAX(ts.Timestamp) AS end_time,
    ROUND(MAX(ts.value) - MIN(ts.value), 2) AS value,
    ts.logicalId
FROM PLANT1.DATA_TABLE AS ts
WHERE ts.unixTime BETWEEN @startTimeInput AND @endTimeInput
GROUP BY 
    ts.logicalId,
    -- 核心分桶逻辑:计算所属窗口序号
    FLOOR((ts.unixTime - @startTimeInput) / @windowMs)
ORDER BY start_time;

方案2:基于Timestamp时间字段实现

如果需要直接传入时间类型参数,可使用该方案:

DECLARE @startTimeInput DATETIME = '2021-11-08 00:00:09.000'; -- 替换为你实际的查询起始时间
DECLARE @endTimeInput DATETIME = '2021-11-08 00:29:09.000'; -- 替换为你实际的查询结束时间
DECLARE @windowMin INT = 15; -- 窗口长度,单位分钟

SELECT 
    MIN(ts.Timestamp) AS start_time,
    MAX(ts.Timestamp) AS end_time,
    ROUND(MAX(ts.value) - MIN(ts.value), 2) AS value,
    ts.logicalId
FROM PLANT1.DATA_TABLE AS ts
WHERE ts.Timestamp BETWEEN @startTimeInput AND @endTimeInput
GROUP BY 
    ts.logicalId,
    -- 核心分桶逻辑:计算所属窗口序号
    DATEDIFF(MINUTE, @startTimeInput, ts.Timestamp) / @windowMin
ORDER BY start_time;

补充说明

如果需要窗口对齐自然时间的15分钟刻度(比如00:00、00:15、00:30等,而非按你传入的起始时间偏移),只需要把分组计算里的@startTimeInput替换为固定基准时间(比如unixTime对应的'1970-01-01 00:00:00')即可。

性能优化建议

如果该查询需要频繁执行,可以给unixTime(或Timestamp)、logicalId、value建立联合覆盖索引,查询时直接走索引无需回表,性能会进一步提升。

内容的提问来源于stack exchange,提问作者Catalyst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 13:45:08