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

如何基于Datetime列按1小时间隔获取一年的SQL数据?

解决按1小时间隔获取年度数据的SQL问题

首先,你的原SQL语句存在两个核心问题:

  • GROUP BY HOUR(DateTime)会把所有日期中同一小时的数据(比如2017-03-01 09点、2017-03-02 09点...)合并成一组,而不是你需要的「每天每小时」的间隔分组;
  • SELECT子句中的ColumnT、ColumnV等列既不在GROUP BY中,也没有使用聚合函数,这会触发SQL的分组规则错误(部分宽松模式的数据库可能返回不可预料的结果)。

下面根据不同的需求场景,给出对应的可行方案:

场景1:每小时取一条数据(最新/最早)

如果你需要每个小时区间内的第一条或最新一条数据,可以用窗口函数ROW_NUMBER()来实现:

WITH HourlyData AS (
    SELECT 
        datetime,
        ColumnT,
        ColumnV,
        ColumnVV,
        -- 按「日期+小时」分组,每组内按datetime排序(DESC取最新,ASC取最早)
        ROW_NUMBER() OVER (PARTITION BY CAST(datetime AS DATE), DATEPART(HOUR, datetime) ORDER BY datetime DESC) AS rn
    FROM [Server].[dbo].[Table]
    WHERE ColumnT LIKE 'XXXX' 
      AND DateTime BETWEEN '2017-03-01 09:00:00' AND '2018-03-01 09:00:00'
)
SELECT datetime, ColumnT, ColumnV, ColumnVV
FROM HourlyData
WHERE rn = 1; -- 筛选出每组的第一条数据

场景2:每小时的聚合统计数据

如果需要对每小时的数据做聚合计算(比如平均值、总和、最大值等),可以对非分组列使用聚合函数:

SELECT 
    -- 生成每小时的起始时间作为分组标识
    DATEADD(HOUR, DATEPART(HOUR, datetime), CAST(CAST(datetime AS DATE) AS DATETIME)) AS HourStart,
    ColumnT, -- 因为WHERE中限定了ColumnT LIKE 'XXXX',所以可以直接包含在GROUP BY中
    AVG(ColumnV) AS Avg_ColumnV, -- 示例:计算ColumnV的小时平均值
    MAX(ColumnVV) AS Max_ColumnVV -- 示例:计算ColumnVV的小时最大值
FROM [Server].[dbo].[Table]
WHERE ColumnT LIKE 'XXXX' 
  AND DateTime BETWEEN '2017-03-01 09:00:00' AND '2018-03-01 09:00:00'
GROUP BY CAST(datetime AS DATE), DATEPART(HOUR, datetime), ColumnT
ORDER BY HourStart;

场景3:生成连续的小时序列(无数据也显示)

如果需要确保每一个小时区间都出现在结果中(即使该小时没有数据),可以先生成连续的小时序列,再左连接原表数据:

-- 生成从起始到结束的所有小时点
WITH HourlySequence AS (
    SELECT CAST('2017-03-01 09:00:00' AS DATETIME) AS HourStart
    UNION ALL
    SELECT DATEADD(HOUR, 1, HourStart)
    FROM HourlySequence
    WHERE HourStart < '2018-03-01 09:00:00'
),
-- 处理原表的小时数据,筛选出每小时最新的一条
TableHourly AS (
    SELECT 
        DATEADD(HOUR, DATEPART(HOUR, datetime), CAST(CAST(datetime AS DATE) AS DATETIME)) AS HourStart,
        ColumnT,
        ColumnV,
        ColumnVV,
        ROW_NUMBER() OVER (PARTITION BY CAST(datetime AS DATE), DATEPART(HOUR, datetime) ORDER BY datetime DESC) AS rn
    FROM [Server].[dbo].[Table]
    WHERE ColumnT LIKE 'XXXX' 
      AND DateTime BETWEEN '2017-03-01 09:00:00' AND '2018-03-01 09:00:00'
)
SELECT 
    hs.HourStart,
    th.ColumnT,
    th.ColumnV,
    th.ColumnVV
FROM HourlySequence hs
LEFT JOIN TableHourly th ON hs.HourStart = th.HourStart AND th.rn = 1
ORDER BY hs.HourStart;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:42:11