【问题标题】:While Loop Problems: Math in SQLWhile 循环问题:SQL 中的数学
【发布时间】:2015-08-06 06:07:36
【问题描述】:

我编写了一个程序,将 1 中的所有数字加到给定数字上(输入 3 - 你得到 6,4 你得到 10,等等)。我认为这是一段有趣的小代码,所以我想我会把它变成一个 while 循环(你启动循环,它会输出所有内容直到一个特定的数字。

问题: 我需要做什么才能把它变成一个while循环?

我有什么

CREATE Procedure MATH 
@InNumber INT,  
@OutNumber INT OUTPUT 

AS
BEGIN

WHILE @InNumber <= 0
RETURN @OutNumber -1;

BEGIN 
  SET @OutNumber=((@InNumber)*(@InNumber+1))/2)
END

 PRINT @OutNumber;
END

【问题讨论】:

  • SET @OutNumber=((@InNumber)*(@InNumber+1))/2) 已经在使用高斯公式对整数求和。为什么你认为你需要一个 while 循环?
  • "只要@InNumber 小于零,就一直返回比@OutNumber 的初始值小一作为完成状态。启动一个复合语句以包含一个使用计算值的语句LISP。(或作者由括号支付。)结束复合语句。打印计算值。有一些机会可以清理这段代码。

标签: sql sql-server tsql while-loop


【解决方案1】:

这不是一个合理的 SQL 设计 - 请改用 tally table,如下所示:

with E1(N) AS ( 
  select N from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1) )E1(N)
),                                             --10E+1 or          10 rows
E2(N) as (select 1 from E1 a cross join E1 b), --10E+2 or         100 rows
E4(N) as (select 1 from E2 a cross join E2 b), --10E+4 or      10,000 rows
E8(N) as (select 1 from E4 a cross join E4 b), --10E+8 or 100,000,000 rows
cteTally(N) as (
  select top (@InNumber)
    row_number() over (order by (select null)) 
  from E8
)
select sum(N) 
from cteTally;

Tally 表非常有用,以至于在大多数数据库中都存在一个永久的 Tally 表,其中包含许多行,可以处理该数据库的大多数应用程序。例如,在支持抵押贷款计算的数据库中,11,000 行足以处理每天 30 年抵押贷款的一行(如 30 * 366 = 10,980)。

然后有了一个名为 dbo.Tally 的永久计数表,代码就变得简单了:

select sum(N) 
from dbo.Tally
were N <= @InNumber;

在 SQL 中使用 WHILE 循环是一种可怕的代码气味。它们有时可能是必需的,但在 30 多年的编程中,我可以用一只手的手指数数我不得不使用一只手的次数。

更新

当然,正如上面的评论员所指出的,无论这种实现多么有效,真正合理的设计都会在已知存在的情况下使用封闭式公式(在本例中为高斯公式)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-26
    • 2011-06-19
    • 1970-01-01
    • 2016-01-04
    • 2022-01-05
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    相关资源
    最近更新 更多