SQL分页查询的写法总结-MySQL、SQL Server、Oracle

MySQL的分页实现是使用LIMIT关键字。

Oracle的分页是实现主要是基于rownum行号。

SQL Server的分页主要使用的关键字是TOP。

具体用法总结如下:

本文中的变量名词说明:

1,分页一般有两个参数,当前页 pageIndex,每页数量 pageSize。

2,实例中查询表名EMP,主键为ID,查询每页数量100条。数据表中共10W条记录。

MySQL分页写法:

LIMIT语法: LIMIT {[offset,] row_count | row_count OFFSET offset}

LIMIT子句可以被用于限制被SELECT语句返回的行数。

使用两个参数时,第一个参数指定返回的偏移量,第二个参数指定返回的行数。初始行的偏移量为0(不是1):

mysql> SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15

使用一个参数时,指定从开头返回的行数:

mysql> SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows

写法实现:

-- 分页查询 通用语句
SELECT * FROM TABLE 
LIMIT (pageIndex-1)*pageSize,pageSize

-- 第一页 每页100条
SELECT * FROM EMP LIMIT 0,100
-- 第二页 每页100条
SELECT * FROM EMP LIMIT 100,100
-- 第801页 每页100条
SELECT * FROM EMP LIMIT 80000,100  -- 用时0.046s

Oracle分页写法:

写法一:ROWNUM 关键字使用

rownum 是伪列,数据库自己创建出来的字段。为每个查询的结果集从1开始生成序号。

rownum不支持>, >=, =, between and,只支持<, <=等。

查询时使用rownum <= 5 返回5条数据,rownum <=10 and rownum >=6 返回0条数据。

为了实现分页,一般使用子查询使rownum成为子查询结果集的具体列。

写法实现:

-- 分页查询 通用语句
SELECT * FROM
	( SELECT ROWNUM AS MYROWNUM, t1.* FROM TABLE t1 ORDER BY ID ) t2 
WHERE MYROWNUM > ( pageIndex - 1 ) * pageSize 
AND MYROWNUM <= pageIndex * pageSize 

-- 第一页 每页100条
SELECT * FROM
	( SELECT ROWNUM AS RN, E.* FROM EMP E ORDER BY ID ) T 
WHERE RN > 0 AND RN <= 100 -- 用时0.023s
-- 第二页 每页100条
SELECT * FROM
	( SELECT ROWNUM AS RN, E.* FROM EMP E ORDER BY ID ) T 
WHERE RN > 100 AND RN <= 200 -- 用时0.026s
-- 第801页 每页100条
SELECT * FROM
	( SELECT ROWNUM AS RN, E.* FROM EMP E ORDER BY ID ) T 
WHERE RN > 800100 AND RN <= 800200 -- 用时0.046s

写法二:利用OFFSET/FETCH NEXT(Oracle 12C 以上版本)

OFFSET/FETCH 语法:

[ OFFSET offset ROWS]
 FETCH  NEXT [  row_count | percent PERCENT  ] ROWS  [ ONLY | WITH TIES ]

1,OFFSET 子句指定在行限制开始之前要跳过行数
2,FETCH 子句指定要返回的行数或百分比
3,简单理解为:offset A rows ,将前A条记录舍去,fetch next B rows only ,向后在读取B条数据

写法实现:

-- 分页查询 通用语句
SELECT * FROM TABLE
OFFSET ( pageIndex - 1 ) * pageSize ROWS 
FETCH NEXT pageIndex * pageSize  ROWS ONLY

-- 第一页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
-- 第二页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 100 ROWS FETCH NEXT 200 ROWS ONLY  -- 用时0.016s
-- 第801页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 80000 ROWS FETCH NEXT 80100 ROWS ONLY  --用时0.135s

SQL Server分页写法:

写法一:使用TOP和子查询

TOP 将在查询结果集中返回的行数限制到指定行数

写法实现:

-- 分页查询 通用语句
SELECT TOP pageSize * FROM TABLE 
WHERE ID NOT IN (
  SELECT TOP (pageIndex-1)*pageSize ID FROM TABLE
)

-- 第一页 每页100条
select top 100 * from EMP  --where id not in (select top 0 id from emp )
-- 第二页 每页100条
select top 100 * from EMP  where id not in (select top 100 id from emp )
-- 第801页 每页100条
select top 100 * from EMP  where id not in (select top 80000 id from emp )

写法二:利用row_number()函数返回行号实现(2005版本以上)

row_number() over(order by id)函数计算出行数,利用子查询即可实现,可结合top使用。

写法实现:

-- 分页查询 通用语句
SELECT TOP pageSize * FROM 
(select row_number() over(order by id )  AS myrownumber,* from TABLE) t 
WHERE  myrownumber > (pageIndex-1)*pageSize
--或者使用 <=
SELECT * FROM 
(select row_number() over(order by id )  AS myrownumber,* from TABLE) t 
WHERE  myrownumber > (pageIndex-1)*pageSize and myrownumber <= pageIndex*pageSize


-- 第一页 每页100条
select top 100 * from EMP  
select TEMP.* from (select row_number() over(order by id )  AS rownumber,* from EMP) TEMP where rownumber >0 and rownumber <=100

-- 第801页 每页100条
select top 100 TEMP.* from (select row_number() over(order by id )  AS rownumber,* from EMP) TEMP where rownumber >80000
select TEMP.* from (select row_number() over(order by id )  AS rownumber,* from EMP) TEMP where rownumber >80000 and rownumber <=80100

写法三:利用 ORDER BY 子句 OFFSET/FETCH

适用于:SQL Server 2012 (11.x) 及更高版本和 Azure SQL 数据库。

OFFSET 和 FETCH 语法:

-- Syntax for SQL Server and Azure SQL Database  
  
ORDER BY order_by_expression  
    [ COLLATE collation_name ]   
    [ ASC | DESC ]   
    [ ,...n ]   
[  ]  
  
 ::=  
{   
    OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }  
    [  
      FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY  
    ]  
}

1,OFFSET 指定开始从查询表达式返回行之前跳过的行数。 该值可以是大于或等于零的整数常量或表达式
2,FETCH  指定在处理 OFFSET 子句后返回的行数。 该值可以是大于或等于 1 的整数常量或表达式。
3,要有ORDER BY 没有ORDER BY无法查询到结果

写法实现:

-- 分页查询 通用语句
SELECT * FROM TABLE 
ORDER BY ID
OFFSET ( pageIndex - 1 ) * pageSize ROWS 
FETCH NEXT pageIndex * pageSize  ROWS ONLY

-- 第一页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
-- 第二页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 100 ROWS FETCH NEXT 200 ROWS ONLY 
-- 第801页 每页100条
SELECT * FROM EMP ORDER BY ID OFFSET 80000 ROWS FETCH NEXT 80100 ROWS ONLY 

提示:

SQL Sever限制行数推荐使用TOP(或 OFFSET 和 FETCH):

使用 TOP(或 OFFSET 和 FETCH)而非 SET ROWCOUNT 限制返回的行数。 这些方法之所以优于使用 SET ROWCOUNT,原因包括以下各项:

  • 作为 SELECT 语句的一部分,查询优化器在查询优化期间可能会考虑 TOP 或 FETCH 子句中 expression 的值。 由于在运行查询的语句外部使用 SET ROWCOUNT,不会在查询计划中考虑它的值。

你可能感兴趣的:(SQL优化,mysql,sql,oracle)