【发布时间】:2013-09-28 11:58:52
【问题描述】:
在其他一些数据库(例如 DB2 或带有 ROWNUM 的 Oracle)中,我可以在排名函数的 OVER() 子句中省略 ORDER BY 子句。例如:
ROW_NUMBER() OVER()
这在与有序派生表一起使用时特别有用,例如:
SELECT t.*, ROW_NUMBER() OVER()
FROM (
SELECT ...
ORDER BY
) t
如何在 SQL Server 中进行模拟?我发现有人使用thistrick,但这是错误的,因为它对于派生表中的顺序的行为是不确定的:
-- 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 子句,因为派生表可能不可用,因为它可能由某些外部逻辑提供。
那我该怎么做呢?我能做到吗?
【问题讨论】:
-
SELECT NULL怎么样?它还会给出无效的结果吗? -
@491243:是的。好吧,结果显然是“有效的”,但我想知道空
OVER()的行为是否真的定义明确,或者这是否在 DB2 上巧合......我将准备一个 SQL Fiddle 来说明这个 -
您需要将 row_number 放在内部查询中,所以如果您无法修改,我认为您不走运。
-
@Laurence:有两个问题。 1)我不一定有权访问内部查询,2)内部查询可能包含
DISTINCT,如果添加ROW_NUMBER()会改变内部查询的语义。 -
嗯,我也是认为的。但我想知道 ;-)
标签: sql sql-server tsql window-functions ranking-functions