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

如何在SQL中创建WHILE循环并避免子查询错误,sql,sql-server,Sql,Sql Server,我将为以下等式找到最佳系数Z: [Target] = Z * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2)) 我的数据集中大约有100000行未达到目标级别。所以,我要找到通过目标层的最小Z值。每一行都是相同的,因此一行可能需要Z=34.5,另一行可能需要Z=13.5。我想编写一个代码,通过循环检查每一行,直到所有行都达到所需的目标级别,并打印所有行的最佳Z值 我编写了如下代码: While (Select [T

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

[Target] = Z * SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))
我的数据集中大约有100000行未达到目标级别。所以,我要找到通过目标层的最小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 
运行此查询后,出现以下错误:

子查询返回了多个值。当子查询在=、!=、=或者当子查询用作表达式时


你知道我如何修复这个错误吗?你相信这个代码能解决我的问题吗?我感谢你的帮助

您希望迭代dbo.product表中的每个记录,并根据条件更新Z和目标列。请理解,从我所看到的,循环的唯一真正目的是找到一个足够大的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 > 1000 / SQRT(Mu_L * POWER(Sigma_D,2) + POWER(Mu_D,2) * POWER(Sigma_L,2))
剩下的唯一诀窍是Z以0.5的增量出现,因此我们应该四舍五入到最接近的0.5。我们可以使用Z的这个公式来求解目标的相应值。这将导致以下代码,它不需要任何类型的循环:

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

由于要确保所有[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 

从dbo中选择[Target]。product返回一个记录集,不能将记录集与整数进行比较。可以使用COUNT函数作为COUNTTarget@ydoow谢谢你的评论。事实上,我看到了微软的While函数的例子,并且有几乎相同的比较。从Production.Product<$300中选择AVGListPrice,而从dbo.Product<1000中选择MIN[Target]时应该选择它,因为您希望确保所有[Target]都>=1000。如果要将数据库表视为电子表格,最好使用真正的电子表格产品。理想情况下,在SQL中,您可以生成基于集合的解决方案,也就是说,这里听起来您应该有一个包含所有可能Z值的表,然后使用合适的条件将这两个表连接在一起,这样您就可以为每一行选择与您的条件相匹配的最低Z值。非常感谢您提供此智能解决方案。但我需要在每次迭代中计算一些其他参数,因此我需要创建一个循环。如果你能帮我弄清楚,我会很感激的。很公平。您得到的错误是因为您的SELECT实际上返回了多个记录all records。你需要对记录进行迭代。现在我明白了这里出了什么问题!是选择返回所有记录。但是你知道我怎样才能重复这些记录吗?@Ashkan看一看。非常感谢你的帮助!我这里有个问题。这段代码在每次迭代时更新所有Z。这意味着在最后,它为所有行提供了唯一的Z值。而我正在寻找每一行的最小Z,这导致目标大于1000。您能帮我解决这个问题吗?因此,在第一个查询中,您可能只想更新[Target]不符合您的目标的行,并且将参与更新。我已经修改了答案供你参考。您可能还希望在第二个查询中使用相同的WHERE子句以获得更好的性能。While循环中的If条件Break Else Continue似乎是多余的。它测试的条件与While中的相同。@spencer7593您是对的。我只是把线路放在那里以防万一OP把它放在那里是有原因的。