繁体   English   中英

为派生表计算SQL Server ROW_NUMBER()OVER()

[英]Calculating SQL Server ROW_NUMBER() OVER() for a derived table

在一些其他数据库(例如DB2或带有ROWNUM Oracle)中,我可以省略排名函数的OVER()子句中的ORDER BY子句。 例如:

ROW_NUMBER() OVER()

当与有序派生表一起使用时,这尤其有用,例如:

SELECT t.*, ROW_NUMBER() OVER()
FROM (
    SELECT ...
    ORDER BY
) t

如何在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

一个具体的例子(可以在SQLFiddle看到 ):

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)

此外,我不能重用派生表中的任何表达式来重现我的情况下的ORDER BY子句,因为派生表可能不可用,因为它可能由某些外部逻辑提供。

那我该怎么办呢? 我可以这样做吗?

Row_Number() OVER (ORDER BY (SELECT 1))欺骗应该被看作是一种以避免改变底层数据的顺序。 它只是避免使服务器执行额外和不需要的排序的一种方法(它可能仍然执行排序,但与按列排序相比,它将花费最小的可能性)。

SQL服务器中的所有查询绝对必须在最外层查询中有一个ORDER BY子句,以便以保证的方式可靠地排序结果。

关系数据库中不存在“保留原始顺序”的概念。 除非在最外层查询中指定了ORDER BY子句,否则必须始终将表和查询视为无序。

您可以尝试相同的无序查询100,000次并始终以相同的顺序接收它,因此相信您可以依赖于所述排序。 但那将是一个错误,因为有一天,某些东西会发生变化而且它不会有你期望的顺序。 一个示例是当数据库升级到新版本的SQL Server时 - 这导致许多查询更改其排序。 但它不一定是那么大的改变。 添加或删除索引的东西可能会导致差异。 还有更多:安装Service Pack。 分区表。 创建包含相关表的索引视图。 达到一些临界点,选择扫描而不是搜索。 等等。

除非您说“Server, ORDER BY ”,否则不要依赖于订购结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM