我应该避免在SQL中使用循环吗?

我应该避免在SQL中使用循环吗?,sql,sql-server,Sql,Sql Server,我创建了一个存储过程来处理这些表上的数据 为了处理这些数据,我必须进行while循环,因为我必须计算一个表中不存在的结束日期 第一条记录的结束日期应为第二条记录的开始日期-1天 现在,当我向我的大四学生介绍这个时,他告诉我,在存储过程中使用循环是一个很大的禁忌。我的前辈提供的解决方案是使用该表创建一个视图,并在其上创建多个联合,以生成我所需的缺失数据 我的循环方法错了吗?将来我是否应该避免在存储过程中使用循环?在处理可能需要循环的问题时,使用基于集合的方法总是一个好主意 几乎所有的while/f

我创建了一个存储过程来处理这些表上的数据

为了处理这些数据,我必须进行while循环,因为我必须计算一个表中不存在的结束日期

第一条记录的结束日期应为第二条记录的开始日期-1天

现在,当我向我的大四学生介绍这个时,他告诉我,在存储过程中使用循环是一个很大的禁忌。我的前辈提供的解决方案是使用该表创建一个视图,并在其上创建多个联合,以生成我所需的缺失数据


我的循环方法错了吗?将来我是否应该避免在存储过程中使用循环?

在处理可能需要循环的问题时,使用基于集合的方法总是一个好主意

几乎所有的while/for循环都可以通过条件连接进行交换,以使其基于集合。如果您需要计数器,请尝试使用理货台

使用JOIN将循环转换为Set问题的示例如下所示

SELECT DISTINCT A.StartDate, B.EndDate
FROM
A LEFT JOIN B
ON DATEDIFF(d,A.EndDate,B.StartDate)=1

最好包含代码和示例数据,以说明您的情况,并使用给定示例数据的示例结果集描述所需的结果。见:和

几乎总是最好避免任何形式的while或游标。在您描述的情况下,我相信您可以通过利用窗口函数避免while循环或多个联合查询

使用带有的示例:

在派生表/内联视图中使用的示例:

select cte.*
  , EndDate = dateadd(day, -1, NextStartDate)
from (
  select t.*
    , NextStartDate = lead(StartDate) over (
        partition by ForEachOfThisColumn -- e.g. AccountId, AssignmentId
        order by StartDate asc
      )
  from t
  ) as cte;

SQL是声明性的;存储过程是过程性的。在求助于存储过程之前,我会尽我所能,看看是否能够以声明的方式满足需求。没有循环。循环通常是一个不错的选择。试着在没有人的情况下做这件事。在循环中执行的逐行处理也被称为“慢到慢”。如果不使用循环,您可以在循环中使用窗口表达式。。。分区或使用复杂连接。在90%左右的情况下,循环在SQL中不是很好的实践。循环是迭代的,不能像基于集合的方法那样优化。使用数字表是一种简洁的选择,请阅读以下内容:
select cte.*
  , EndDate = dateadd(day, -1, NextStartDate)
from (
  select t.*
    , NextStartDate = lead(StartDate) over (
        partition by ForEachOfThisColumn -- e.g. AccountId, AssignmentId
        order by StartDate asc
      )
  from t
  ) as cte;