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

SQL Server:如何将循环生成的多个单行结果合并为单表?

问题描述

我有一份按分钟记录数据的数据集,需要统计指定月份内每日的列平均值。目前编写的循环查询能得到正确结果,但返回的是31个各含1行的独立结果集,而非1个包含31行的单表。请问该现象的原因是什么?如何将这些结果合并为单表?

当前使用的查询代码:

SET NOCOUNT ON;
DECLARE @StartDate DateTime
SET @StartDate = dateadd(day,datediff(day,1,getdate()),0) -- 11.12.2023

DECLARE @EndDate DateTime
SET @EndDate = dateadd(day,datediff(day,0,getdate()),0) --11.13.2023

DECLARE @CurrentMonthStart DateTime
SET @CurrentMonthStart = dateadd(month,datediff(month,0,getdate()),0) -- 11.01.2023 stop date for last month
       
DECLARE @LastMonthStart DateTime
SET @LastMonthStart = dateadd(month,-1,@CurrentMonthStart +1) -- 10.02.2023 start with first day of month

DECLARE @EndDateCycle DateTime
SET @EndDateCycle = dateadd(day,1, @LastMonthStart) -- 10.03.2023 reading available full day after

-- Inflow

SET @StartDate = @LastMonthStart -- 10.02.2023
SET @EndDate = @EndDateCycle -- 10.03.2023
WHILE @StartDate <= @CurrentMonthStart -- check to make sure we're still in last month
    BEGIN
        DECLARE @AP Float
        SET @AP = (SELECT
              Avg(AP_INF_FT01MGD_VAL0) --this gets one value, average of the minutely data 
        FROM MINUTELY
        WHERE timestamp >= @StartDate --to loop forward in month, day to day
        AND timestamp < @EndDate)
    SELECT 'Apollo' = @AP,
        'Reading Date' = @StartDate
    WHERE @AP IS NOT NULL -- had to add because I'd get an extra reading with NULL (investigate)
    SET @StartDate = @StartDate + 1 --plus 1 to loop through the month
    SET @EndDate    = @EndDate + 1
    END

实际返回31个独立单行表,预期是包含31行的单表。


问题原因

你当前的循环逻辑中,每次循环都会执行一次SELECT语句,每执行一次SELECT就会返回一个独立的结果集。循环跑31次,自然就输出31个单独的单行结果集。


解决方法

方法1:修改循环逻辑,用临时表合并结果

在循环前创建临时表存储每次计算的结果,循环结束后一次性查询临时表内容,就能得到单表结果:

SET NOCOUNT ON;
DECLARE @StartDate DateTime
SET @StartDate = dateadd(day,datediff(day,1,getdate()),0) -- 11.12.2023

DECLARE @EndDate DateTime
SET @EndDate = dateadd(day,datediff(day,0,getdate()),0) --11.13.2023

DECLARE @CurrentMonthStart DateTime
SET @CurrentMonthStart = dateadd(month,datediff(month,0,getdate()),0) -- 11.01.2023 stop date for last month
       
DECLARE @LastMonthStart DateTime
SET @LastMonthStart = dateadd(month,-1,@CurrentMonthStart +1) -- 10.02.2023 start with first day of month

DECLARE @EndDateCycle DateTime
SET @EndDateCycle = dateadd(day,1, @LastMonthStart) -- 10.03.2023 reading available full day after

-- 创建临时表存储结果
CREATE TABLE #DailyAverages (
    Apollo FLOAT,
    [Reading Date] DATETIME
)

-- Inflow
SET @StartDate = @LastMonthStart -- 10.02.2023
SET @EndDate = @EndDateCycle -- 10.03.2023
WHILE @StartDate <= @CurrentMonthStart -- check to make sure we're still in last month
    BEGIN
        DECLARE @AP Float
        SET @AP = (SELECT
              Avg(AP_INF_FT01MGD_VAL0) --this gets one value, average of the minutely data 
        FROM MINUTELY
        WHERE timestamp >= @StartDate --to loop forward in month, day to day
        AND timestamp < @EndDate)
        
        -- 将结果插入临时表,而非直接输出
        INSERT INTO #DailyAverages (Apollo, [Reading Date])
        SELECT @AP, @StartDate
        WHERE @AP IS NOT NULL -- 过滤NULL值
        
        SET @StartDate = @StartDate + 1 --plus 1 to loop through the month
        SET @EndDate    = @EndDate + 1
    END

-- 一次性输出所有结果
SELECT Apollo, [Reading Date] FROM #DailyAverages

-- 删除临时表
DROP TABLE #DailyAverages

方法2:用分组查询替代循环(更高效)

SQL里循环通常效率偏低,推荐直接按日期分组计算每日平均值,无需循环:

SET NOCOUNT ON;

DECLARE @CurrentMonthStart DateTime
SET @CurrentMonthStart = dateadd(month,datediff(month,0,getdate()),0) -- 11.01.2023
       
DECLARE @LastMonthStart DateTime
SET @LastMonthStart = dateadd(month,-1,@CurrentMonthStart +1) -- 10.02.2023

SELECT 
    Avg(AP_INF_FT01MGD_VAL0) AS Apollo,
    CAST(timestamp AS DATE) AS [Reading Date]
FROM MINUTELY
WHERE timestamp >= @LastMonthStart 
  AND timestamp < @CurrentMonthStart
GROUP BY CAST(timestamp AS DATE)
ORDER BY [Reading Date]

这个查询通过CAST(timestamp AS DATE)把分钟级数据按日期分组,直接计算每日平均值,返回的就是包含所有日期结果的单表,同时避免了循环带来的性能损耗。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 10:10:33