Luk*_*der 12 sql t-sql sql-server window-functions ranking-functions
在一些其他数据库(例如DB2或Oracle ROWNUM)中,我可以省略ORDER BY排名函数子句中的OVER()子句.例如:
ROW_NUMBER() OVER()
Run Code Online (Sandbox Code Playgroud)
当与有序派生表一起使用时,这尤其有用,例如:
SELECT t.*, ROW_NUMBER() OVER()
FROM (
SELECT ...
ORDER BY
) t
Run Code Online (Sandbox Code Playgroud)
如何在SQL Server中进行模拟?我发现人们使用这个 技巧,但这是错误的,因为它对于派生表中的顺序会表现得非确定:
-- This order here ---------------------vvvvvvvv
SELECT t.*, ROW_NUMBER() OVER(ORDER BY (SELECT 1))
FROM (
SELECT TOP 100 PERCENT ...
-- vvvvv ----redefines this order here
ORDER BY
) t
Run Code Online (Sandbox Code Playgroud)
SELECT v, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM (
SELECT TOP 100 PERCENT 1 UNION ALL
SELECT TOP 100 PERCENT 2 UNION ALL
SELECT TOP 100 PERCENT 3 UNION ALL
SELECT TOP 100 PERCENT 4
-- This descending order is not maintained in the outer query
ORDER BY 1 DESC
) t(v)
Run Code Online (Sandbox Code Playgroud)
此外,我不能重用派生表中的任何表达式来重现ORDER BY我的情况,因为派生表可能不可用,因为它可能由某些外部逻辑提供.
那我该怎么办呢?我可以这样做吗?
Eri*_*ikE 10
该Row_Number() OVER (ORDER BY (SELECT 1))技巧应该不被视为一种方式,以避免改变底层数据的顺序.它只是为了避免使所述服务器执行附加的和不需要的排序的装置(它可能仍然执行排序,但它会比由列排序时花费的最小量可能).
SQL服务器中的所有查询绝对必须ORDER BY在最外层查询中有一个子句,以便以保证的方式可靠地排序结果.
关系数据库中不存在"保留原始顺序"的概念.除非ORDER BY在最外层查询中指定了子句,否则必须始终将表和查询视为无序.
您可以尝试相同的无序查询100,000次并始终以相同的顺序接收它,因此相信您可以依赖于所述排序.但那将是一个错误,因为有一天,某些东西会发生变化而且它不会有你期望的顺序.一个示例是当数据库升级到新版本的SQL Server时 - 这导致许多查询更改其排序.但它不一定是那么大的改变.添加或删除索引的东西可能会导致差异.还有更多:安装Service Pack.分区表.创建包含相关表的索引视图.达到一些临界点,选择扫描而不是搜索.等等.
除非您说"服务器",否则不要依赖于订购结果ORDER BY.
| 归档时间: |
|
| 查看次数: |
38515 次 |
| 最近记录: |