我有一个带有计算的SQL Server查询,我想称之为'my_long_calculation',我在查询中的几个地方使用它。问题是我不知道如何将'my_long_calculation'计算存储到变量中以便于阅读。
所以这是计算:
(FLOOR(DATEPART(DAY, DATEADD(MINUTE, [table1].someInt, [table1].someDate)) / 1440.0) % 2) + 1
它的作用对这个问题并不重要。重要的是这个计算很难写。
现在我在查询中的几个地方使用相同的计算(不要试图理解它,只是注意有几个地方我使用相同的计算,但我不在{ {1}}语句,仅在SELECT
和JOIN
语句中:
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语句
上使用它答案 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