TSQL OVER CLAUSE具有Order By子句的没有分区

时间:2013-09-02 08:25:17

标签: sql-server tsql window partitioning clause

我在阅读像

这样的代码时遇到了问题
SELECT 
    employeeID as ID,
    RANK() OVER (ORDER BY AVG (Salary) DESC) AS Value 
FROM Salaries 

据称可以获得每位员工的平均工资

我的理解是代码应该是

SELECT 
    employeeID as ID,
    RANK() OVER (Partition By employeeID ORDER BY AVG (Salary) DESC) AS Value 
FROM Salaries 

但上面的代码工作正常吗?

1 个答案:

答案 0 :(得分:1)

第一个不适合我(返回 Msg 8120 列''Salaries.employeeID'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中),直到我添加group by employeeID

SELECT 
    employeeID as ID,
    RANK() OVER (ORDER BY AVG (Salary) DESC) AS Value 
FROM Salaries
GROUP BY employeeID

也许,为了更好地理解,它可以被等效地重写为:

;with cte as (
    SELECT employeeID, AVG (Salary) as AvgSalary
    FROM Salaries
    GROUP BY employeeID
)
select employeeID as ID
    , RANK() OVER (ORDER BY AvgSalary DESC) as Value
    --, AvgSalary
from cte

在这种情况下,员工的平均工资在CTE中计算,然后通过排名列Value扩展查询。将partition by employeeID添加到over子句:

;with cte as (
    SELECT employeeID, AVG (Salary) as AvgSalary
    FROM Salaries
    GROUP BY employeeID
)
select employeeID as ID
    , RANK() OVER (partition by employeeID ORDER BY AvgSalary DESC) as Value
    --, AvgSalary
from cte
对于结果集中的每一行,

将导致Value = 1(这似乎无法实现),因为rank()会为每个不同的employeeID重置编号为1 ,employeeID在每一行都是不同的,因为在排名之前,此列汇总了数据。