【问题标题】:Help with RANK() Over Scalar Function - SQL Server 2008帮助 RANK() Over Scalar Function - SQL Server 2008
【发布时间】:2011-06-12 19:18:50
【问题描述】:

我有以下内联表值函数:

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) 吗?

【问题讨论】:

  • 如果没有Order By,那不就是随机选择10个值吗?
  • @Thomas - 调用存储过程中有一个 OrderBy。
  • 由于OVER (ORDER BY...,RANK 函数将正确分配值。结果集的顺序未定义。
  • 没错。我不关心这个函数的排序,它只需要返回一组 RANK 值。存储的过程加入此函数并按等级值排序。 编辑: 我删除了 TOP(10) - 它应该在调用存储过程中,因此造成混乱。

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


【解决方案1】:

是的,您不能在 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   

【讨论】:

  • 太棒了,谢谢。我真的需要开始学习 CTE ——因为我在 SQL Server 2000 上花费了我 70% 的开发人员生命,我错过了所有这些很棒的东西。 :) 在 45 秒内接受您的回答...
【解决方案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

【讨论】:

  • 是的,这是另一种选择。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 2016-04-05
  • 1970-01-01
  • 2022-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多