举例子:下面这段代码是错误的!!!
select max(avg(sal)) "部门平均工资的最大值",deptno "部门编号" from emp group by deptno;
为啥是错误的呢???分组中我们已经有了deptno字段了,而我们select 后面跟着也就是多行函数和该字段而已,为啥就错了呢?????我们如果在分组查询的时候,使用了多行函数嵌套的话,那么我们select字段后面只能跟随着它这么一个列,而不能再多了。max(avg(sal)) 相当于又分组了一次
当然了,如果我们仅仅是求出每个部门的平均工资,也就是下面这段代码,是完全没有问题的:
select avg(sal) "部门平均工资的最大值",deptno "部门编号" from emp group by deptno;
多表查询、子查询
当我们一张表不能把数据查询出来的时候,就需要连接其他的表一起查询….
当我们的查询条件还没知道的时候,我们就可以使用子查询….
一般地,子查询和多表查询的功能都是差不多的….
子查询出来的数据是单行单列的时候,一般我们都是用等于、大于等于、小于等操作符去限制查询条件…
如果是单列多行的时候,我们一般都是用IN、ANY、ALL操作符去筛选条件…
如果是多行多列,我们就看成该返回查询结果是一张表【Oracle分页就是这个原理】
值得注意的是多表查询的数学基础是笛卡尔积,也就是说:如果两张实体表进行连接,那么它会构成一张笛卡尔积表…也就是说:最终就只有一张笛卡尔积表
连接
在多表查询的时候,我们由于会产生笛卡尔积,于是在笛卡尔积表中会存在很多无关的数据…为了剔除这些数据,我们将用到where字句将笛卡尔积表筛选成有用的数据表
一般地,我们有几种连接:
- 内连接
- 等值连接【使用=号把条件筛选出来】
- 非等值连接【使用between and等手段把条件筛选】
- 外连接
- 自连接
那现在问题来了,在Oracle中有的功能我们可以使用多表查询来完成,有的时候我们又可以使用子查询来完成,那么我们一般选择哪一个呢????
我们看下图来比较一下他们的优劣:
对于索引就是一个以空间换时间的概念..在数据量很大的时候,Oracle会为我们的数据创建索引,当扫描数据的时候,就可以根据索引来直接获取值….索引的算法也有几种【二叉树、稀疏索引、位图索引….等等】
综上所述:在Oracle中使用多表查询性能可能比子查询好一些
Oracle分页
在讲解JDBC的时候,我们就已经讲过Oracle与Mysql的分页问题了….详情可以看我的博文:http://blog.csdn.net/hon_3y/article/details/53790092
我们在这里还是加深一下印象:
Oracle中的分页是依靠着rownum这个伪列来实现的,由于rownum只能使用的是<=或者<来获取数据。。。因为rownum的值可能会经常变【加入一条数据,那么rownum就+1,讲道理rownum可以是无穷大的,因此不能使用>来进行操作】….
那么Oracle分页的思路是这样子的:
- 先在子查询中获取前n条记录
- 由于返回的是多行多列,因此我们可以看做成一张表
- 那么将查询出来的数据放在from字句的后边
- 外套的查询可以通过where字句来对子查询出来的数据进行过滤
- 那么我们就可以查询出想要的数据了…
公式:
- Mysql从(currentPage-1)*lineSize开始取数据,取lineSize条数据
- Oracle先获取currentPagelineSize条数据,从(currentPage-1)lineSize开始取数据
小面试题
笔试题:有【1000亿】条会员记录,如何用最高效的方式将薪水字段清零,其它字段内容不变?
第一:从emp表中删除sal字段
- alter table emp
- drop column sal;
第二:向emp表中添加sal字段,且内容默认0
- alter table emp
- add sal number(6) default 0;
操作表细节
进入回收站 drop table users; 查询回收站中的对象 show recyclebin; 闪回,即将回收站还原 flashback table 表名 to before drop; flashback table 表名 to before drop rename to 新表名; 彻底删除users表 drop table users purge; 清空回收站 purge recyclebin; 为emp表增加image列,alter table 表名 add 列名 类型(宽度) alter table emp add image blob; 修改ename列的长度为20个字节,alter table 表名 modify 列名 类型(宽度) alter table emp modify ename varchar2(20); 删除image列,alter table 表名 drop column 列名 alter table emp drop column image; 重名列名ename为username,alter table 表名 rename column 原列名 to 新列名 alter table emp rename column ename to username; 将emp表重命名emps,rename 原表名 to 新表名 rename emp to emps;
- number(5):
- 最多5位数字
- number(6,2):
- 其中2表示最多显示2位小数,采用四舍五入,不足位数补0,同时要设置col … for …
- 其中6表示小数+整数不多于6位
- 其中整数位数不得多于4位,可以等于4位
- varchar2(8):
- 8表示字节
值得注意的是:修改表的时候,是不能回滚的!
Oracle中的级联操作:
- 【on delete cascade】级联删除
- 【on delete set null】将外键一方设置为null