Sql server SQL错误-Windows函数只能出现在SELECT或ORDER BY子句中

Sql server SQL错误-Windows函数只能出现在SELECT或ORDER BY子句中,sql-server,tsql,ddl,calculated-columns,window-functions,Sql Server,Tsql,Ddl,Calculated Columns,Window Functions,我对SQL相对来说是新手,我正试图找出为什么我会在文章标题中出现错误。(我认为这与滞后函数有关?) 以下是我试图执行的代码: ALTER TABLE [MyDatabase].[dbo].[MyTable] ADD Calc_Column AS CAST ( CASE WHEN [Variable_X] = LAG([Variable_X],1,0) OVER (Order By FileDate) AND [Variable_Y] != LAG([Variable

我对SQL相对来说是新手,我正试图找出为什么我会在文章标题中出现错误。(我认为这与滞后函数有关?)

以下是我试图执行的代码:

ALTER TABLE [MyDatabase].[dbo].[MyTable]
ADD Calc_Column AS CAST
(
    CASE WHEN [Variable_X]  = LAG([Variable_X],1,0) OVER (Order By FileDate)
          AND [Variable_Y] != LAG([Variable_Y],1,0) OVER (Order By FileDate) 
          AND [ACTUAL START DATE] != 0
          AND [FileDate] >= [ACTUAL START DATE]
         THEN 1
         ELSE 0
    END AS N
)
GO

错误信息非常清楚:在这种情况下,您可以使用窗口函数(
lag
),而不是
select
子句或
order by
子句。
计算列只能引用函数或当前行中的值,不能在其声明中直接包含select语句。
但它可以使用用户定义的标量函数进行计算,所以如果您真的想计算使用窗口函数计算的列,则必须使用用户定义的函数进行计算。我曾尝试为您创建一个示例函数,但由于您没有共享表的DDL,因此我不得不进行假设和猜测,并且无法对其进行测试,因此它可能不完全适合。但是,它应该足以显示总体思路,并且您应该能够根据自己的需要对其进行修改

CREATE FUNCTION dbo.CalculateMyColumn
(
    -- Assuming an int identity column with ascending order
    @PrimaryKeyColumn int 
)
Returns Bit
AS
BEGIN
    DECLARE @ReturnValue bit

    ;WITH cte AS
    (
        SELECT Variable_X, 
               LAG([Variable_X],1,0) OVER (Order By FileDate) As Prev_Variable_X,
               Variable_Y, 
               LAG([Variable_Y],1,0) OVER (Order By FileDate) As Prev_Variable_Y,
               [ACTUAL START DATE], 
               [FileDate],
               PrimaryKeyColumn
        FROM TableName
        WHERE PrimaryKeyColumn <= @PrimaryKeyColumn
    )

    SELECT @ReturnValue = 
            CASE WHEN Variable_X = Prev_Variable_X
                 AND Variable_Y != Prev_Variable_Y
                 AND [ACTUAL START DATE] != 0
                 AND [FileDate] >= [ACTUAL START DATE]
            THEN 1
            ELSE 0
            END
    FROM cte
    WHERE PrimaryKeyColumn = @PrimaryKeyColumn

END

请注意此函数依赖于主键列为升序的int-identity列

错误信息非常清楚:在这种情况下,您可以使用窗口功能(
lag
),在
select
子句或
order by
子句之外的任何位置。
计算列只能引用函数或当前行中的值,不能在其声明中直接包含select语句。
但它可以使用用户定义的标量函数进行计算,所以如果您真的想计算使用窗口函数计算的列,则必须使用用户定义的函数进行计算。我曾尝试为您创建一个示例函数,但由于您没有共享表的DDL,因此我不得不进行假设和猜测,并且无法对其进行测试,因此它可能不完全适合。但是,它应该足以显示总体思路,并且您应该能够根据自己的需要对其进行修改

CREATE FUNCTION dbo.CalculateMyColumn
(
    -- Assuming an int identity column with ascending order
    @PrimaryKeyColumn int 
)
Returns Bit
AS
BEGIN
    DECLARE @ReturnValue bit

    ;WITH cte AS
    (
        SELECT Variable_X, 
               LAG([Variable_X],1,0) OVER (Order By FileDate) As Prev_Variable_X,
               Variable_Y, 
               LAG([Variable_Y],1,0) OVER (Order By FileDate) As Prev_Variable_Y,
               [ACTUAL START DATE], 
               [FileDate],
               PrimaryKeyColumn
        FROM TableName
        WHERE PrimaryKeyColumn <= @PrimaryKeyColumn
    )

    SELECT @ReturnValue = 
            CASE WHEN Variable_X = Prev_Variable_X
                 AND Variable_Y != Prev_Variable_Y
                 AND [ACTUAL START DATE] != 0
                 AND [FileDate] >= [ACTUAL START DATE]
            THEN 1
            ELSE 0
            END
    FROM cte
    WHERE PrimaryKeyColumn = @PrimaryKeyColumn

END

请注意此函数依赖于主键列为升序的int-identity列

错误信息的哪一部分不清楚?请给我们一个样本数据和预期结果。谢谢。错误中说窗口功能只能在
选择
按顺序
中使用,因此不能在
情况下使用
statement@mitchmitch24 . . . 您可以使用此功能的视图。错误消息的哪一部分不清楚?请给我们一个示例数据和预期结果。谢谢。错误中说窗口功能只能在
选择
按顺序
中使用,因此不能在
情况下使用
statement@mitchmitch24 . . . 您可以使用视图来实现此功能。做得好-这是我要建议的,但有一个重要的警告:计算列的T-SQL标量UDF、检查约束或其他相关内容都是性能杀手。即使并行计划更好,它们的存在也会导致优化器选择串行执行计划。请注意Eric Darling的这篇伟大的文章:计算列中的标量函数是个坏主意的另一个原因()。@AlanBurstein感谢链接!我知道标量UDF通常意味着性能不好,但我不知道有任何其他方法可以让计算列依赖于内置函数和当前行数据之外的任何内容。也许Gordon提出的创建视图的建议是一个更好的解决方案。做得好-这是我要建议的,但有一个重要的警告:计算列的T-SQL标量UDF、检查约束或其他相关内容都是性能杀手。即使并行计划更好,它们的存在也会导致优化器选择串行执行计划。请注意Eric Darling的这篇伟大的文章:计算列中的标量函数是个坏主意的另一个原因()。@AlanBurstein感谢链接!我知道标量UDF通常意味着性能不好,但我不知道有任何其他方法可以让计算列依赖于内置函数和当前行数据之外的任何内容。也许戈登提出观点的建议是一个更好的解决方案。