如何在SQL中创建WHILE循环并避免子查询错误

时间:2016-09-01 04:32:04

标签: sql sql-server

我将为以下等式找到最佳系数(Z)

[Target] = Z * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))

我的数据集中有大约100,000行不符合Target级别。因此,我将找到传递目标级别的最小Z值。每行都相同,因此一行可能需要Z=34.5而另一行可能需要Z=13.5。我想编写一个代码来检查循环中的每一行,直到所有行都满足所需的目标级别,并为所有行打印最佳Z值。

我写了这样的代码:

While (Select [Target] From dbo.product) < 1000 
Begin
   Update dbo.product 
   SET [Z] = Z + 0.5

   Update dbo.product 
   SET [Target] = Z * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))

   IF (Select [Target] From dbo.product) > 1000
      Break
   Else
      Continue 
End 

运行此查询后,出现以下错误:

  

子查询返回的值超过1。当子查询遵循=,!=,&lt;,&lt; =,&gt;,&gt; =或子查询用作表达式时,不允许这样做。

您是否知道如何解决此错误?你也相信这段代码可以解决我的问题吗?感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您希望迭代dbo.product表中的每条记录,并根据条件更新ZTarget列。从我所看到的,欣赏循环的唯一真正目的是找到Z的值,该值足够大以使循环退出并进行赋值。但实际上,我们可以为每条记录提供Z值的公式,而不用循环显式迭代:

[Target] = Z * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))

[Target]超过1000时,循环将中断,这会导致以下不等式:

1000 < Z * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))

但我们可以解决Z,导致这种不平等:

Z > 1000 / SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))

唯一剩下的技巧是Z0.5为增量,因此我们应该将向上舍入到最近的0.5。我们可以使用Z的此公式来求解Target的相应值。这导致以下代码,它不需要任何类型的循环:

GO
BEGIN
    UPDATE dbo.product 
    SET [Z] = FLOOR((1000 / SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2)) + 0.4) * 2) / 2
    UPDATE dbo.product 
    SET [Target] = [Z] * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))
END

答案 1 :(得分:1)

如果您想确保[Target] >= 1000的所有行,请使用MIN查找值最小的行。

While (Select MIN([Target]) From dbo.product) < 1000 
Begin
   Update dbo.product 
   SET [Z] = Z + 0.5
   WHERE [Target] < 1000

   Update dbo.product 
   SET [Target] = Z * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))

   IF (Select MIN([Target]) From dbo.product) > 1000
      Break
   Else
      Continue 
End