按行ROW_NUMBER

Ale*_*ecs 2 sql t-sql

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()函数一起使用.有人可以向我解释一下吗?

bea*_*ach 7

当然可以通过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)


gbn*_*gbn 3

您不能直接按 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)

但这没有任何意义:我知道你的问题是关于它如何工作的抽象问题,这是一个不清楚的问题。如果您用简单的英语和示例输入和输出描述您想要的内容,那就更有意义了