SQL Server循环查询结果分表:如何合并为单个结果表
解决SQL Server循环输出多个结果集合并问题
你的问题出在WHILE循环内每次执行SELECT都会生成独立的结果集,而非将数据累积到同一个集合中。另外注意你原代码里的一个错误:@endDate的赋值语句误写为读取startDate,这会导致DATEDIFF(day, @startDate, @endDate)结果为0,循环根本不会执行,需要先修正这个问题。
下面提供两种可行的解决方案:
方案1:使用表变量存储结果(兼容你的循环逻辑)
声明一个表变量来存储所有生成的日期行,循环内用INSERT INTO替代直接SELECT,最后一次性输出所有数据:
DECLARE @Counter INT = 0 DECLARE @startDate DATE = (SELECT startDate FROM [Table] WHERE ID = 334) DECLARE @endDate DATE = (SELECT endDate FROM [Table] WHERE ID = 334) -- 修正:读取endDate而非startDate -- 声明表变量存储结果 DECLARE @ResultTable TABLE ( startDate DATE, endDate DATE ) WHILE @Counter < DATEDIFF(day, @startDate, @endDate) BEGIN INSERT INTO @ResultTable (startDate, endDate) SELECT DATEADD(day, @Counter, @startDate), DATEADD(day, @Counter + 1, @startDate) SET @Counter = @Counter + 1 END -- 最后统一输出合并后的结果 SELECT startDate, endDate FROM @ResultTable
方案2:使用递归CTE(更高效的集合操作,推荐)
SQL Server更适合用集合操作替代循环,递归CTE可以直接生成连续日期范围并合并为单个结果集:
DECLARE @startDate DATE = (SELECT startDate FROM [Table] WHERE ID = 334) DECLARE @endDate DATE = (SELECT endDate FROM [Table] WHERE ID = 334) WITH DateRange AS ( SELECT @startDate AS startDate, DATEADD(day, 1, @startDate) AS endDate UNION ALL SELECT DATEADD(day, 1, startDate), DATEADD(day, 1, endDate) FROM DateRange WHERE startDate < DATEADD(day, -1, @endDate) ) SELECT startDate, endDate FROM DateRange OPTION (MAXRECURSION 0) -- 如果日期范围超过100天需要加这个选项,默认递归次数限制为100
说明
- 方案1保留了你原来的循环逻辑,只是通过表变量累积数据;
- 方案2是SQL Server中生成连续日期范围的标准做法,性能远优于循环,尤其当日期范围较大时;
- 注意原代码中
[Table]是关键字,建议用方括号包裹避免语法错误。
内容的提问来源于stack exchange,提问作者Nate
相关产品推荐
相关产品推荐

