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

存储过程查询需求:按日期去重返回单设备每日数据

解决方案:实现每日一行的设备数据查询

问题根源

你当前使用的DISTINCT无法实现每日一行的原因是:它会对SELECT子句中的所有列(DEVICE, VALUE, DATE, DATE1)做去重判断。只要同一天内存在不同的VALUE或带时间部分的DATE1,就会被判定为不同行,导致重复结果。

修正方案

根据需求,我们需要按日期维度分组,从每天的多条记录中筛选出单条有效数据(或做聚合计算),这里提供两种常用实现方式:

方式1:取每天的最新/最早记录

使用ROW_NUMBER()窗口函数,按设备+日期分组,对每天的记录按时间排序后取第一行:

WITH DailyData AS (
    SELECT 
        DEVICE, 
        VALUE, 
        DATE, 
        DATE1,
        -- 按设备+日期分组,按时间倒序(取最新)或正序(取最早)排序
        ROW_NUMBER() OVER (PARTITION BY DEVICE, CAST(DATE1 AS DATE) ORDER BY DATE1 DESC) AS RowNum
    FROM tableName 
    WHERE 
        DEVICE = @DeviceId 
        -- 修正时间范围条件:确保记录时间在传入的起止区间内
        AND DATE1 >= @StartDate 
        AND DATE1 <= @EndDate 
        AND ABS(VALUE) >= 0
)
SELECT DEVICE, VALUE, DATE, DATE1
FROM DailyData
WHERE RowNum = 1
ORDER BY DATE1 ASC

如果需要取当天最早的记录,只需把ORDER BY DATE1 DESC改为ORDER BY DATE1 ASC。

方式2:对每日数据做聚合计算

如果不需要单条记录,而是需要当天数据的统计值(如平均值、最大值、总和),可以用GROUP BY实现:

SELECT 
    DEVICE,
    -- 根据业务需求选择聚合函数,比如平均值、最大值
    AVG(VALUE) AS DailyAvgValue,
    -- 取日期部分
    CAST(DATE1 AS DATE) AS RecordDate,
    -- 可选:取当天的第一个/最后一个时间戳
    MIN(DATE1) AS FirstRecordTime,
    MAX(DATE1) AS LastRecordTime
FROM tableName 
WHERE 
    DEVICE = @DeviceId 
    AND DATE1 >= @StartDate 
    AND DATE1 <= @EndDate 
    AND ABS(VALUE) >= 0
GROUP BY DEVICE, CAST(DATE1 AS DATE)
ORDER BY RecordDate ASC

适配小时级查询

以上两种方案都天然支持小时级范围查询:

  • 当传入2023-12-25 10:00:00至2023-12-25 13:00:00时,CAST(DATE1 AS DATE)会统一为2023-12-25,最终返回该日期下符合时间范围的单条记录(或聚合值)。
  • 如果查询跨天的小时范围(如2023-12-25 22:00:00至2023-12-26 02:00:00),会分别返回两天的对应数据。

修正后的存储过程调用示例

EXEC [dbo].[exampleProcedure] 'ABC','2023-12-25 12:00:00','2024-01-04 15:00:00'

内容的提问来源于stack exchange,提问作者Kadir Çolak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:45:07