主流数据库之间对SQL:2003标准的不同实现方法比较(第二部分 结果集排序)

本文严禁在未征得本人同意的情况下以任何形式进行转载。本人只接受在邮件中的转载申请,如需转载,请发送邮件至 @126.com。  

 

限制结果集<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

简单限制

 

目标:从结果集中取n行数据。通常与ORDER BY表达式联合使用。

 

备注1:这与top-n查询是不同的。

 

备注2:下面的一些查询并非在所有环境下均是合法的,比如在视图或子查询中。

 

标准(Standard)

IDT611的非核心特性指定window函数中的ROW_NUMBER()可以完成此功能:

SELECT * FROM (

   SELECT

      ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,

      columns

FROM tablename

) AS foo

WHERE rownumber <= n

 

如果应用是有状态的(之于无状态的web应用),就可能需要使用游标特性了(ID E121的核心特性)。包括:

DECLARE cursor-name CURSOR FOR …

OPEN cursor-name

FETCH …

CLOSE cursor-name

PostgreSQL

不支持ROW_NUMBER()。支持游标(不仅在嵌入式、动态SQL中,而且在所有上下文中)

 

ROW_NUMBER()的替代解决方案:

 

SELECT columns

FROM tablename

ORDER BY key ASC

LIMIT n

 

注意LIMIT改变了SELECT … FOR UPDATE的语义

DB2

支持标准中的两种方法。对于一般性工作来说,可使用DB2的非标准语句来构造:

 

SELECT … FETCH FIRST n ROWS ONLY

MS SQL Server

支持表准中的两种方法。

 

MSSQL 2000不支持ROW_NUMBER()MSSQL 2000需要使用以下替代方法:

 

SELECT TOP n columns

FROM tablename

ORDER BY key ASC

 

TOP关键字在MSSQL 2005中依然可用。

MySQL

不支持标准。替代方案为:

 

SELECT columns

FROM tablename

ORDER BY key ASC

LIMIT n

Oracle

支持ROW_NUMBER。仿佛有非标准的游标工具。

 

由于Oracle在子查询的命名中不支持AS(在本例中无需对子查询命名),所以标准SQL代码需要进行简单修改:

 

SELECT * FROM (

SELECT

    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,

    Columns

FROM tablename

)

WHERE rownumber <= n

 

原文参考:Comparison of different SQL implementations

阅读更多
换一批

没有更多推荐了,返回首页