我正在使用CTE根据销售排名对书籍作者进行排名。我了解ROW_NUMBER()
可以使用ORDER BY
来确定基于它的返回行号。
我的查询如下:
WITH cte (idWork, author, rn)
AS
(
SELECT
idWork,
authorName,
ROW_NUMBER() OVER (PARTITION BY idWork ORDER BY authorSalesRank)
FROM dbo.Works_Authors_Works
INNER JOIN Authors ON Authors.idAuthor = Works_Authors_Works.idAuthor
)
SELECT TOP 100 * FROM cte
我注意到结果看起来像这样,这是预期的:
+---------+----------------+------+
| idWork | author | rn |
+---------+----------------+------+
| 1 | test1 | 1 |
| 1 | test2 | 2 |
| 1 | test3 | 3 |
| 2 | beep1 | 1 |
| 2 | beep2 | 2 |
| 3 | nobody | 1 |
+---------+----------------+------+
我对此CTE有两个问题:
ROW_NUMBER
字段rn
上排序?就像结果在idWork
上分组然后在rn
上排序一样?例如,当idWork
为1时,行在rn
上从1,2,然后3排序。这是巧合还是总是这样?SELECT TOP 1 * FROM cte WHERE idWork = 1
,它是否会始终返回rn
= 1的行?在执行计划中,它有一个输入排序idWork
,authorSalesRank
。这些暗示外部结果也是这样排序的吗?
答案 0 :(得分:3)
您应该明确订购它。
WITH cte (idWork, author, rn) AS (
SELECT
idWork,
authorName,
ROW_NUMBER() OVER (PARTITION BY idWork ORDER BY authorSalesRank) AS rn
FROM dbo.Works_Authors_Works
INNER JOIN Authors ON Authors.idAuthor = Works_Authors_Works.idAuthor
)
SELECT TOP 100 *
FROM cte
order by idWork, rn
如果没有指定订单,SQL(所有数据库)都不保证订单,即使似乎喜欢它“总是有效”,你也不应该依赖那个轶事证据。