UPD:感谢所有人,主题关闭,睡觉后我明白了一切=)
我在理解OVER子句和ROW_NUMBER函数时遇到问题.简单的表 - 名称和标记.我想计算每个名字的平均分数.
SELECT top 1 with ties name, ROW_NUMBER() over (PARTITION BY name ORDER BY name) as number
FROM table
ORDER BY AVG(mark) OVER(PARTITION BY name)
Run Code Online (Sandbox Code Playgroud)
它会显示这样的东西,我理解为什么 - 这就是ROW_NUMBER()的作用
name|number
Pete 1
Pete 2
Run Code Online (Sandbox Code Playgroud)
但如果我写
SELECT top 1 with ties name, ROW_NUMBER() over (PARTITION BY name ORDER BY name) as number
FROM table
ORDER BY AVG(mark) OVER(PARTITION BY name), number
Run Code Online (Sandbox Code Playgroud)
它会显示出来
name|number
Pete 1
Run Code Online (Sandbox Code Playgroud)
而这次我不明白ORDER BY如何与ROW_NUMBER()函数一起使用.有人可以向我解释一下吗?
您当然可以通过ROW_NUMBER列进行排序,因为SELECT子句是在ORDER BY子句之前计算的.您可以按任何列或列别名进行ORDER BY .这就是没有抛出错误消息的原因(因为它是有效的).
SELECT name, ROW_NUMBER() over (PARTITION BY name ORDER BY name) as number
FROM @table
ORDER BY number
Run Code Online (Sandbox Code Playgroud)
评估到
name number
---------- --------------------
John 1
pete 1
pete 2
John 2
pete 3
Run Code Online (Sandbox Code Playgroud)
OP的第二个row_number示例不正确.
SELECT AVG(mark) OVER(PARTITION BY name), name, ROW_NUMBER() over (PARTITION BY name ORDER BY name) as number
FROM @table
ORDER BY AVG(mark) OVER(PARTITION BY name), number
Run Code Online (Sandbox Code Playgroud)
返回预期,因为AVG是第一个排序后跟数字的排序列.
name number
----------- ---------- --------------------
11 pete 1
11 pete 2
11 pete 3
17 John 1
17 John 2
Run Code Online (Sandbox Code Playgroud)
将查询更改为编号DESC,pete仍然是第一个,但行号是降序.
name number
----------- ---------- --------------------
11 pete 3
11 pete 2
11 pete 1
17 John 2
17 John 1
Run Code Online (Sandbox Code Playgroud)
SQL操作顺序
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
Run Code Online (Sandbox Code Playgroud)
您不能直接按 ROW_NUMBER 进行排序:我不知道为什么在这种情况下您没有收到错误,但通常情况下您会收到错误。因此使用派生表或 CTE
SELECT
name, number
FROM
(
SELECT
name,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) as number,
AVG(mark) OVER (PARTITION BY name) AS nameavg
FROM table
) foo
ORDER BY
nameavg, number
Run Code Online (Sandbox Code Playgroud)
但是,PARTITION BY name ORDER BY name 是没有意义的。每个分区都有随机顺序,因为排序就是分区
我怀疑你想要这样的东西,其中 ROW_NUMBER 基于 AVG
SELECT
name, number
FROM
(
SELECT
name,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY nameavg) AS number
FROM
(
SELECT
name,
AVG(mark) OVER (PARTITION BY name) AS nameavg
FROM table
) foo
) bar
ORDER BY
number
Run Code Online (Sandbox Code Playgroud)
或者更传统(但名称已折叠为平均值)
SELECT
name, number
FROM
(
SELECT
name,
ROW_NUMBER() OVER (PARTITION BY name ORDER BY nameavg) AS number
FROM
(
SELECT
name,
AVG(mark) AS nameavg
FROM
table
GROUP BY
name
) foo
) bar
ORDER BY
number
Run Code Online (Sandbox Code Playgroud)
您也许可以将派生的 foo 和 bar 合二为一
ROW_NUMBER() OVER (PARTITION BY name ORDER BY AVG(mark))
Run Code Online (Sandbox Code Playgroud)
但这没有任何意义:我知道你的问题是关于它如何工作的抽象问题,这是一个不清楚的问题。如果您用简单的英语和示例输入和输出描述您想要的内容,那就更有意义了