嵌套计算列"无效列名"错误(T-SQL列别名)

时间:2017-02-25 17:27:39

标签: sql-server tsql alias calculated-columns

我创建了3个计算列作为别名,然后使用别名列来计算总费用。这是查询:

SELECT TOP 1000 [Id]
      ,[QuantityOfProduct]
      ,[Redundant_ProductName]
      ,[Order_Id]
      ,(CASE 
            WHEN [PriceForUnitOverride] is NULL 
                THEN [Redundant_PriceForUnit]
            ELSE
                [PriceForUnitOverride]
        END
        ) AS [FinalPriceForUnit]

      ,(CASE 
            WHEN [QuantityUnit_Override] is NULL 
                THEN [Redundant_QuantityUnit]
            ELSE
                [QuantityUnit_Override]
        END
        ) AS [FinalQuantityUnit]

      ,(CASE 
            WHEN [QuantityAtomic_Override] is NULL 
                THEN [Redundant_QuantityAtomic]
            ELSE
                [QuantityAtomic_Override]
        END
        ) AS [Final_QuantityAtomic]

         --***THIS IS WHERE THE QUERY CREATES AN ERROR***--
        ,([QuantityOfProduct]*[FinalPriceForUnit]*
  ([Final_QuantityAtomic]/[FinalQuantityUnit])) AS [Final_TotalPrice]


  FROM [dbo].[ItemInOrder]

  WHERE [IsSoftDeleted] = 0
  ORDER BY [Order_Id] 

控制台返回此错误消息:

Msg 207, Level 16, State 1, Line 55
Invalid column name 'FinalPriceForUnit'.
Msg 207, Level 16, State 1, Line 55
Invalid column name 'Final_QuantityAtomic'.
Msg 207, Level 16, State 1, Line 55
Invalid column name 'FinalQuantityUnit'.

如果我删除" AS [Final_TotalPrice]"别名计算列,没有错误发生,但我需要总价。我该如何解决这个问题?似乎在达到Final_TotalPrice时尚未创建其他别名。

2 个答案:

答案 0 :(得分:2)

您不能在同一个选择中使用别名。你可以做的是在子查询中找到值,然后在表达式中使用它(或者可以在表达式中重复整个case语句)。另外,请使用COALESCE代替CASE

select t.*,
    ([QuantityOfProduct] * [FinalPriceForUnit] * ([Final_QuantityAtomic] / [FinalQuantityUnit])) as [Final_TotalPrice]
from (
    select top 1000 [Id],
        [QuantityOfProduct],
        [Redundant_ProductName],
        [Order_Id],
        coalesce([PriceForUnitOverride], [Redundant_PriceForUnit]) as [FinalPriceForUnit],
        coalesce([QuantityUnit_Override], [Redundant_QuantityUnit]) as [FinalQuantityUnit],
        coalesce([QuantityAtomic_Override], [Redundant_QuantityAtomic]) as [Final_QuantityAtomic]
    from [dbo].[ItemInOrder]
    where [IsSoftDeleted] = 0
    order by [Order_Id]
    ) t;

答案 1 :(得分:2)

您不能在同一个选择中使用表别名。正常的解决方案是CTE或子查询。但是,SQL Server还提供APPLY。 (Oracle还支持APPLY和其他数据库,例如Postgres使用LATERAL关键字支持横向连接。)

我喜欢这个解决方案,因为您可以创建任意嵌套的表达式,而不必担心缩进:

SELECT TOP 1000 io.Id, io.QuantityOfProduct, io.Redundant_ProductName,
       io.Order_Id,
       x.FinalPriceForUnit, x.FinalQuantityUnit, x.Final_QuantityAtomic,
       (x.QuantityOfProduct * x.FinalPriceForUnit * x.Final_QuantityAtomic / x.FinalQuantityUnit
       ) as Final_TotalPrice
FROM dbo.ItemInOrder io OUTER APPLY
     (SELECT COALESCE(PriceForUnitOverride, Redundant_PriceForUnit) as FinalPriceForUnit,
             COALESCE(QuantityUnit_Override, Redundant_QuantityUnit) as FinalQuantityUnit
             COALESCE(QuantityAtomic_Override, Redundant_QuantityAtomic) as Final_QuantityAtomic
     ) x
WHERE io.IsSoftDeleted = 0
ORDER BY io.Order_Id ;

注意:

  • 我发现[]根本无法帮助我阅读或撰写查询。
  • COALESCE()CASE语句简单得多。
  • 使用COALESCE(),您可以考虑将COALESCE()表达式放在最终计算中。