【问题标题】:How While loop in SQL worksSQL 中的 While 循环如何工作
【发布时间】:2019-01-22 09:45:42
【问题描述】:

我正在使用 sql 中的 While 循环,并尝试在这些日期应用代码。

DECLARE @StartDate DATETIME = '2018-08-01';
DECLARE @EndDate DATETIME = '2018-08-15';

WHILE @StartDate < @EndDate

BEGIN

SELECT @StartDate 
SET @StartDate = @StartDate+1

END;

当我运行它时,虽然我希望它在同一个窗口中,但我会在多个窗口中获得输出。

【问题讨论】:

  • 创建一个临时表并在每次迭代时插入,当循环退出时,选择你的临时表。
  • 或者用PRINT @StartDate代替SELECT @StartDate
  • 您实际上想要完成什么?这闻起来像 XY 问题 (xyproblem.info)
  • 不要使用 + 来添加日期...这种方法有时会起作用,最终你会得到意想不到的结果。即,如果您使用其他日期类型,或者您想添加除一天之外的其他内容。总是使用dateadd 来避免这种情况。
  • 例如,基于集合的处理方法可能假设您已经在数据库中构建了一个 calendar 表(每天一行,列您可能每天都想知道有趣的事情,例如您的组织是否认为这是一个工作日)。然后,您只需从该表中获取SELECT,其中日期位于您的两个端点之间。 (很多人对日历表的想法有一个直觉的反应——“它最终不会包含很多行吗?”——没有意识到 20 年小于 10000。非常小)

标签: sql sql-server


【解决方案1】:

您的循环正在进行选择,因此循环的每次迭代都会提供一个新的查询结果窗口。如果您希望它作为一个结果集返回,则必须将其插入表中并选择循环之外的所有内容。

DECLARE @StartDate DATETIME = '2018-08-01';
DECLARE @EndDate DATETIME = '2018-08-15';
DECLARE @table TABLE (yourdate DATETIME)
WHILE @StartDate < @EndDate

BEGIN

INSERT INTO @table (yourdate)
SELECT @startdate 
SET @StartDate = @StartDate+1

END;

SELECT * 
FROM @Table

【讨论】:

  • 这个答案实际上解决了 OP 提出的“为什么会发生这种情况”的问题,而不是直接跳到“你应该这样做”。 +1 从海报的位置开始。
【解决方案2】:

您可以将recursive waycommon_table_expression 一起使用:

DECLARE @StartDate DATETIME = '2018-08-01';
DECLARE @EndDate DATETIME = '2018-08-15';

WITH t AS (
     SELECT @StartDate AS Startdate
     UNION ALL
     SELECT DATEADD(DAY, 1, Startdate)
     FROM t
     WHERE Startdate < @EndDate 
)

SELECT Startdate
FROM t;

【讨论】:

  • 由于递归 CTE 可能难以理解,因此简要说明或介绍链接可能有助于了解其工作原理。
  • 这看起来像是一种基于集合的方法,但实际上使用这样的递归 cte 仍然是 RBAR。看看这篇文章。 sqlservercentral.com/articles/T-SQL/74118
【解决方案3】:

尝试使用#temp 表,因为每当循环运行时,您都会选择一个新的SELECT 语句,这就是它出现在不同窗口中的原因。要在一个窗口中获取所有结果,您可以尝试CTE#temp 表。

DECLARE @StartDate DATETIME = '2018-08-01';
DECLARE @EndDate DATETIME = '2018-08-15';

CREATE TABLE #Temp 
(
Date date
)

WHILE @StartDate < @EndDate

BEGIN

INSERT INTO #Temp VALUES (@StartDate)

SET @StartDate = @StartDate+1

END;

SELECT * FROM #Temp

【讨论】:

    猜你喜欢
    • 2011-01-19
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 2012-05-17
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多