Sql 在存储过程中使用聚合函数一次而不是多次

Sql 在存储过程中使用聚合函数一次而不是多次,sql,tsql,Sql,Tsql,我有一个存储过程,其中使用了一个函数,该函数需要两个参数。 我的问题与性能问题有关,请参见下文 CASE WHEN (DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeID), dbo.FunctionName(DatetimeField, DatetimeID))/60.0) > 8 THEN (DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeI

我有一个存储过程,其中使用了一个函数,该函数需要两个参数。 我的问题与性能问题有关,请参见下文

 CASE 
 WHEN (DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeID), dbo.FunctionName(DatetimeField, DatetimeID))/60.0) > 8 THEN
      (DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeID), dbo.FunctionName(DatetimeField, DatetimeID))/60.0)
 Else 0
 END 
 Else
 0
 END)
 Else
(DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeID), dbo.FunctionName(DatetimeField, DatetimeID))/60.0)-T.lunch
END
     as 'Total'
现在我要做的是创建一个临时表,这样我就可以用它来调用函数,而不是每次它到达那些有数十万条记录的行时调用函数的方式。
非常感谢您的帮助。

您可以在如下查询中重用表达式:

select (case when NewValue > 8 then NewValue else 0 end) xyz
from T
cross apply (
 select NewValue = dbo.FunctionName(DatetimeField, DatetimeID)
) x
DECLARE @NewValue int = dbo.FunctionName(DatetimeField, DatetimeID);
以这种特殊方式使用的交叉应用程序可用于引入新列并重用它们的值。这种技术有利于在同一查询中重用公共表达式

正常批处理级别变量可以这样声明:

select (case when NewValue > 8 then NewValue else 0 end) xyz
from T
cross apply (
 select NewValue = dbo.FunctionName(DatetimeField, DatetimeID)
) x
DECLARE @NewValue int = dbo.FunctionName(DatetimeField, DatetimeID);

假设您的函数是确定性的(或至少返回相同的值而不考虑时钟时间),您可以设置一个临时表,如下所示:

select DatetimeField, DatetimeID, FunctionName(DatetimeField, DatetimeID) as val
into #tmp
from (select distinct DatetimeField, DatetimeID
      from table
     ) t
然后,您可以重写存储过程以使用它

但是,在编写查询时,确定性函数只会为datediff返回0,因为这两个参数是相同的


最后,您的性能问题似乎与所调用的函数有关。建议您发布代码是一个很好的建议。

您真正需要帮助的是什么?如何?或者如何进入它?或者如何在查询中使用该表?您自己尝试过什么?如果从表中选择,则
FunctionName
函数做什么可能是性能问题。SQL Server中用户定义的标量函数本质上效率低下(至少在2012年之前)。发布您的dbo.FunctionName()函数,我们可以向您展示如何将其重写为更高效的表值函数。我知道如何编写函数,这很好。我唯一的问题是与性能问题有关,因为这个存储过程需要30秒才能执行。我希望能够将它缩短到10秒以下。我希望以其他方式调用我的函数,而不是像我现在这样调用它一万次。这就是方法只能创建新列。好吧,它不能创造新的变量。也许我误解了你。您可以这样声明一个变量:declare@NewValue int=dbo.FunctionName(DatetimeField,DatetimeID);我知道如何声明变量,但你不能用CROSS-APPLY来声明它们,尽管你的帖子说你可以。@rbaryyoung,我在回答中补充了说明。我希望这对OP有用(虽然他没有提供反馈)。这仍然是错误的。SQL Server中没有“查询级别”变量。您所描述的是虚拟表中的派生列。将其称为任何类型的变量都会产生误导和混淆。