我正在尝试选择第3-5行:
SELECT *
FROM Finance_User
ORDER BY email DESC
我原来只有:
SELECT
ROW_NUMBER() OVER (ORDER BY email DESC) AS RowNum, *
FROM
Finance_User
WHERE
RowNum BETWEEN 3 AND 5
但这无效,因为RowNum
是无效的列。
相反,我做了以下事情:
WITH OrderedUsers AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY email DESC) AS RowNum, *
FROM
Finance_User
)
SELECT *
FROM OrderedUsers
WHERE RowNum BETWEEN 3 AND 5
这很好用。但是,我担心这可能会导致性能问题,因为它似乎是两次从表中选择?
答案 0 :(得分:5)
ROW_NUMBER()
不会扫描表两次。但是,使用窗口功能可能会对RDBMS进行额外的处理。
您可以使用ORDER BY ... OFFSET ... FETCH ...
(从SQL Server 2012开始可用)获得相同的结果,这些结果专门用于分页结果集:
SELECT *
FROM Finance_User
ORDER BY email DESC
OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY
从文档中:
我们建议您使用OFFSET和FETCH子句代替TOP子句来实现查询分页解决方案并限制发送到客户端应用程序的行数。
答案 1 :(得分:3)
您的查询很好。
WITH AS
子句是Common Table Expression,这意味着此查询以后可以重用,并且在需要和可能的情况下应缓存。因此,“两次从表中选择”应该没有任何问题。
通过此查询可以获得相同的结果:
SELECT * from
(SELECT ROW_NUMBER() OVER (ORDER BY email DESC) AS RowNum, * FROM Finance_User)
where RowNum between 3 and 5
最后,您始终可以检查执行计划并确保执行计划。