没有ORDER BY的ROW_NUMBER

luc*_*ucy 23 sql t-sql sql-server window-functions

我要在现有查询中添加行号,以便我可以跟踪已添加到Redis中的数据量.如果我的查询失败,那么我可以从该行开始,而不是在其他表中更新.

查询从表中获取1000行之后的数据

SELECT * FROM (SELECT *, ROW_NUMBER() OVER (Order by (select 1)) as rn ) as X where rn > 1000
Run Code Online (Sandbox Code Playgroud)

查询工作正常.如果有任何方法,我可以获得行没有不使用顺序.

这是什么select 1

查询是否已优化,或者我可以通过其他方式进行查询.请提供更好的解决方案.

got*_*tqn 53

无需担心在ORDER BY表达式中指定常量.以下内容引自Microsoft SQL Server 2012高性能T-SQL使用窗口函数编写Itzik Ben-Gan(可从Microsoft免费电子书网站免费下载):

如上所述,窗口顺序子句是必需的,SQL Server不允许排序基于常量 - 例如,ORDER BY NULL.但令人惊讶的是,当传递基于返回常量的子查询的表达式时,例如,ORDER BY(SELECT NULL)-SQL Server将接受它.同时,优化器取消或扩展表达式,并意识到所有行的排序都是相同的.因此,它从输入数据中删除了排序要求.这是一个完整的查询,演示了这种技术:

SELECT actid, tranid, val,
 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
FROM dbo.Transactions;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在Index Scan迭代器的属性中观察Ordered属性为False,这意味着迭代器不需要以索引键顺序返回数据


以上意味着当您使用常量排序时不执行.我强烈建议您阅读本书Itzik Ben-Gan,深入介绍窗口功能的工作原理以及如何在使用时优化各种情况.

  • @lucy否,查询的每次执行顺序都不相同。使用(选择常数)表示没有订单。您正在选择特定数量的数据-您可以执行一百万次查询,并返回相同的数据,但这并不能保证。如果没有特定的顺序,结果是不确定的。 (2认同)

Dam*_*ver 7

试试吧order by 1.阅读错误消息.然后恢复order by (select 1).意识到写这篇文章的人在某些时候已经阅读了错误信息,然后决定正确的做法是欺骗系统不引发错误,而不是意识到错误试图提醒他们的基本事实.

表没有固有的顺序.如果您想要某种可以依赖的排序形式,那么您需要为任何ORDER BY子句提供足够的确定性表达式,以便每行都是唯一标识和排序的.

其他任何事情,包括欺骗系统不发出错误,都希望系统能够做一些合理的事情而不使用提供给你的工具来确保它做一些合理的事情 - 一个明确规定的ORDER BY条款.

  • @MikeTeeVee - 这是一个已经被“搞死”的话题。不存在固有的用户可观察的顺序。*通常*从单个表中进行的选择将遵循聚集索引顺序,但 SQL Server 不*保证*情况确实如此。但即使在这种情况下,您也可能会进行轮播扫描 - 您的查询会搭载另一个已经开始表扫描的查询。您的查询开始从表的中间获取结果,因为那是扫描的位置,然后将开始第二次扫描以完成。即使只定义了聚集索引,结果也会乱序。 (3认同)

Luk*_*zda 6

这里的select 1是什么?

在这种情况下,查询的作者实际上并没有考虑任何特定的排序。 ROW_NUMBER要求 ORDER BY clause这样提供它是满足解析器的一种方式。

按“常量”排序将创建“不确定”顺序(查询优化器能够选择它认为合适的任何顺序)。

最简单的思考方式是:

ROW_NUMBER() OVER(ORDER BY 1)    -- error
ROW_NUMBER() OVER(ORDER BY NULL) -- error
Run Code Online (Sandbox Code Playgroud)

有几种可能的情况可以提供常量表达式来“欺骗”查询优化器:

ROW_NUMBER() OVER(ORDER BY (SELECT 1)) -- already presented
Run Code Online (Sandbox Code Playgroud)

其他选项:

ROW_NUMBER() OVER(ORDER BY 1/0)       -- should not be used
ROW_NUMBER() OVER(ORDER BY @@SPID)
ROW_NUMBER() OVER(ORDER BY DB_ID())
ROW_NUMBER() OVER(ORDER BY USER_ID())
Run Code Online (Sandbox Code Playgroud)

db<>小提琴演示


Mad*_*nan 5

您可以使用任何文字值

order by (select 0)

order by (select null)

order by (select 'test')
Run Code Online (Sandbox Code Playgroud)

等等

请参阅此以获取更多信息 https://exploresql.com/2017/03/31/row_number-function-with-no-specific-order/