Oracle学习 第五天
—— Oracle的分页查询
在查询大量数据时,一次性查询所有结果所花费的时间和资源师巨大的。
分页查询即每次返回前n行数据,将数据分页返回。在实际项目中是几乎不可避免,配合前台代码可以方便的展示分页效果,同时每次只返回部分数据的特点也大大的加快了运行效率。
其他数据库的分页查询
MySQL的分页查询
SELECT * FROM table WHERE condition LIMIT num1, num;
其中,num1:从第几条开始查询; num:查询几条记录
SQL Server的分页查询
SELECT TOP num * FROM table WHERE id NOT IN(SELECT TOP num1 FROM table WHERE condition)
其中,num与num1都表示查询几条记录
整句意为:查询table表中 除去在前num1条记录中 的前num条记录。即从(num1 + 1) 条(含) 到 num + num1条(含)
需要注意的是,TOP关键字要求主键不能使联合主键
Oracle数据库的分页查询
首先介绍一个隐藏字段 ROWNUM。这是Oracle中每张数据表都默认自带的一个字段,作用是给查询返回的结果一个从1开始递增的序号。
SELECT EMP.*, ROWNUM FROM EMP;
所以,关于Oracle的分页查询,可以如下写:
SELECT EMP.*, ROWNUM FROM EMP WHERE ROWNUM <= 5;
这条语句很明显返回的是 EMP 表中的前 10 条记录。但是,不要以为Oracle的分页查询仅仅如此简单。
如下:
SELECT EMP.* ROWNUM FROM EMP WHERE ROWNUM <= 5 AND ROWNUM >= 2;
会发现,一条数据也没有???
这是因为在Oracle底层对上述语句的查询执行的效率是相当低的,所以Oracle从底层拒绝了这种语法的使用。
如果想实现如上的分页效果,应该如下写:
SELECT T2.* FROM (SELECT T1.*, ROWNUM RN FROM (SELECT * FROM EMP) T1 WHERE ROWNUM <= 5) T2 WHERE RN >= 2;
上面的语句看似很长,但是,效率上确实要高出很多。
可以看出,这么写是先筛选出 ROWNUM >= 5 的所有数据,然后将其作为虚拟表,在从中筛选 ROWNUM >= 2 的数据。这明显效率要比直接从源表中筛选一次 ROWNUM >= 5 的数据然后又筛选一次 ROWNUM <= 2的数据,再组合 的这种写法高很多
Oracle的分页查询还可以根据ROWID来分页或者使用分析函数进行分页。但并不常用,这里不多介绍。
—— Oracle的合并查询
UNION关键字
该关键字用于取的两个结果集的并集。并且会自动去掉结果集中重复的行。
SELECT ENAME, SAL, JOB FROM EMP WHERE SAL > 2000 UNION SELECT ENAME, SAL, JOB FROM EMP WHERE JOB = 'MANAGER';
★ 注意:两个结果集的列要相同,否则会报错。
SELECT ENAME, SAL FROM EMP WHERE SAL > 2000 UNION SELECT ENAME, SAL, JOB FROM EMP WHERE JOB = 'MANAGER';
UNION ALL关键字
该关键字用法与 UNION 完全一样。唯一的不同是,UNION ALL 不会去除重复行,也不会自动排序。
SELECT ENAME, SAL, JOB FROM EMP WHERE SAL > 2000 UNION ALL SELECT ENAME, SAL, JOB FROM EMP WHERE JOB = 'MANAGER';
INTERSECT关键字
该关键字用于取两个结果集的交集。即两个集合中重复的数据。
SELECT ENAME, SAL, JOB FROM EMP WHERE SAL > 2000 INTERSECT SELECT ENAME, SAL, JOB FROM EMP WHERE JOB = 'MANAGER';
MINUS关键字
该关键字用于取两个结果集的叉集。如:table1 MINUS table2。则取table1 - table2 的部分。即 table1 中包含且 table2 中不包含的数据
SELECT ENAME, SAL, JOB FROM EMP WHERE SAL > 2000 MINUS SELECT ENAME, SAL, JOB FROM EMP WHERE JOB = 'MANAGER';