SQL Server - 在select语句中设置和使用变量

时间:2018-02-14 03:51:43

标签: sql-server

我有一个带有计算的SQL Server查询,我想称之为'my_long_calculation',我在查询中的几个地方使用它。问题是我不知道如何将'my_long_calculation'计算存储到变量中以便于阅读。

所以这是计算:

(FLOOR(DATEPART(DAY, DATEADD(MINUTE, [table1].someInt, [table1].someDate)) / 1440.0) % 2) + 1

它的作用对这个问题并不重要。重要的是这个计算很难写。

现在我在查询中的几个地方使用相同的计算(不要试图理解它,只是注意有几个地方我使用相同的计算,但我不在{ {1}}语句,仅在SELECTJOIN语句中:

WHERE

现在我想像这样写上这个怪物(通过用更短的名字替换相同计算的所有实例):

SELECT
    [table1].ID
FROM 
    [table1]
INNER JOIN 
    [table2] ON [table2].someattribute = (FLOOR(DATEPART(DAY, DATEADD(MINUTE, [table1].someInt, [table1].someDate)) / 1440.0) % 2) + 1
INNER JOIN 
   [table3] ON [User].someattribute = (FLOOR(DATEPART(DAY, DATEADD(MINUTE, [table1].someInt, [table1].someDate)) / 1440.0) % 2) + 1
WHERE 
    (FLOOR(DATEPART(DAY, DATEADD(MINUTE, [table1].someInt, [table1].someDate)) / 1440.0) % 2) + 1 = 1

这两个查询是相同的,我只是替换名称/变量'my_long_calculation'的长计算。

当然,第二个语句会抛出错误,因为未定义“my_long_calculation”。但是,如何在查询中定义和设置变量以提高可读性?

重要提示:我不希望通过将其包含在select语句中来返回长计算。我只想在join和where语句

上使用它

2 个答案:

答案 0 :(得分:1)

根据您删除的评论,您希望在每次迭代中使用它。在这种情况下,您需要创建一个标量函数,

CREATE FUNCTION dbo.LongCalculation 
( 
   @firstParam INT,
   @secondParam DATETIME
) 
  RETURNS NUMERIC(10, 2)   -- specify correct data type here
  AS 
  BEGIN 
      --your logic here
  END 
GO 

并在查询中使用

SELECT
    [table1].ID
FROM 
    [table1]
    INNER JOIN [table2] ON [table2].someattribute =  dbo.LongCalculation([table1].someInt, [table1].someDate)
    INNER JOIN [table3] ON [User].someattribute =  dbo.LongCalculation([table1].someInt, [table1].someDate)
WHERE 
     dbo.LongCalculation([table1].someInt, [table1].someDate) = 1

答案 1 :(得分:1)

最好的方法是创建一个标量值函数,如下所示。通过使用函数,您无需在任何地方编写相同的公式。它更易于维护。

CREATE function [dbo].[ufn_Calculate]
(
@someInt INT,
@someDate DATETIME
)
returns DECIMAL(15,2)

AS

Begin

DECLARE @CalculationOutput DECIMAL(15,2)
SELECT @CalculationOutput = (FLOOR(DATEPART(DAY, DATEADD(MINUTE, @someInt, @someDate)) / 1440.0) % 2) + 1
RETURN @CalculationOutput
End
GO

现在您可以在查询中使用它,如下所示。

 SELECT
    [table1].ID
FROM 
    [table1]
    INNER JOIN [table2] ON [table2].someattribute = [dbo].[ufn_Calculate]([table1].someInt,[table1].someDate)
    INNER JOIN [table3] ON [User].someattribute = [dbo].[ufn_Calculate]([table1].someInt,[table1].someDate)
WHERE 
    [dbo].[ufn_Calculate]([table1].someInt,[table1].someDate) = 1