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)
它会显示这样的内容,我理解为什么 - 这就是ROW_NUMBER()所做的
name|number
Pete 1
Pete 2
但如果我写
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
它会显示
name|number
Pete 1
这次我不明白ORDER BY如何与ROW_NUMBER()函数一起使用。有人可以向我解释一下吗?
答案 0 :(得分:7)
您当然可以通过ROW_NUMBER列进行排序,因为SELECT子句是在ORDER BY子句之前计算的。您可以按任何列或列别名进行排序。这就是没有抛出错误消息的原因(因为它是有效的)。
SELECT name, ROW_NUMBER() over (PARTITION BY name ORDER BY name) as number
FROM @table
ORDER BY number
评估到
name number
---------- --------------------
John 1
pete 1
pete 2
John 2
pete 3
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
按预期返回,因为AVG是第一个排序后跟数字的排序列。
name number
----------- ---------- --------------------
11 pete 1
11 pete 2
11 pete 3
17 John 1
17 John 2
将查询更改为编号DESC ,并且pete仍然是第一个,但行号是降序。
name number
----------- ---------- --------------------
11 pete 3
11 pete 2
11 pete 1
17 John 2
17 John 1
SQL操作顺序
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
答案 1 :(得分: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
然而,PARTITION BY名称ORDER BY名称毫无意义。每个分区都有随机顺序,因为排序是分区
我怀疑你想要这样的东西,其中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
传统上更为传统(但名称因平均而崩溃)
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
您可能将派生的foo和bar折叠成一个
ROW_NUMBER() OVER (PARTITION BY name ORDER BY AVG(mark))
但 none 这是有道理的:我明白你的问题是抽象的如何它的作用有点不清楚问题。如果用简单的英语和样本输入和输出描述你想要的东西会更有意义