帮助RANK()通过标量函数 - SQL Server 2008

时间:2011-01-20 22:19:05

标签: tsql sql-server-2008 ranking user-defined-functions

我有以下内联表值函数:

SELECT   Locations.LocationId, 
         dbo.Search_GetSuitability(@SearchPreferences,
            Score.FieldA, Score.FieldB, Score.FieldC) AS OverallSuitabilityScore,
        RANK() OVER (ORDER BY OverallSuitabilityScore) AS OverallSuitabilityRank

FROM        dbo.LocationsView Locations
INNER JOIN  dbo.LocationScores Score ON Locations.LocationId = Score.LocationId
WHERE       Locations.CityId = @LocationId   

那条RANK()行给了我一个错误:

  

无效的列名称'OverallSuitabilityScore'。

函数dbo.Search_GetSuitability标量函数,返回DECIMAL(8,5)。我需要根据该值为每一行分配一个等级。

我可以让上述工作的唯一方法是再次在ORDER BY部分添加标量函数调用 - 这很愚蠢。我有大约5个这些标量函数调用,我需要为每个调用单独的RANK()值。

我该怎么办?我可以使用公用表表达式(CTE)吗?

2 个答案:

答案 0 :(得分:4)

是的,您无法在SELECT子句中引用列别名。然而,CTE听起来不错。这是一个例子

WITH Score as
    (
    select Score.LocationId, Score.FieldA, Score.FieldB, Score.FieldC,
        dbo.Search_GetSuitability(@SearchPreferences,
            Score.FieldA, Score.FieldB, Score.FieldC) AS OverallSuitabilityScore
    from dbo.LocationScores
    )

SELECT   TOP(10) 
         Locations.LocationId, 
         Score.OverallSuitabilityScore,
        RANK() OVER (ORDER BY OverallSuitabilityScore) AS OverallSuitabilityRank

FROM        dbo.LocationsView Locations
INNER JOIN  Score ON Locations.LocationId = Score.LocationId
WHERE       Locations.CityId = @LocationId   

答案 1 :(得分:2)

旧学校这样做的方法就是向SUBQUERY表达。 此处的CTE仅将子查询移动到顶部

SELECT   TOP(10) LocationId, 
        OverallSuitabilityScore,
        RANK() OVER (ORDER BY OverallSuitabilityScore) AS OverallSuitabilityRank
FROM
(
    SELECT
         Locations.LocationId, 
         dbo.Search_GetSuitability(@SearchPreferences,
             Score.FieldA, Score.FieldB, Score.FieldC) AS OverallSuitabilityScore
    FROM        dbo.LocationsView Locations
    INNER JOIN  dbo.LocationScores Score ON Locations.LocationId = Score.LocationId
    WHERE       Locations.CityId = @LocationId   
) X