按部就班学Oracle之复杂查询(重点)

前言sql

在实际应用中常常须要执行复杂的数据统计,常常须要显示多张表的数据,故必需要高度重视: 复杂的select语句!数据库

1-数据分组的重要函数: max、min、avg、sum、countide

(1)查询出全部员工中最高薪水和最低薪水者及其姓名的信息.函数

p_w_picpath

p_w_picpath

(2)查询出全部员工的平均工资和工资总和性能

p_w_picpath

(3)计算共有多少员工测试

p_w_picpath

(4)查询出工资最高和最低的员工的名字、工做岗位大数据

p_w_picpath

(5)查询出工资高于平均工资的员工信息spa

p_w_picpath

(6)查询出工资低于平均工资和入职日期在1982年12月1日以前的员工且他们的工资都上涨10%后的信息排序

p_w_picpath

2-group by 和having子句get

group by用于对查询的结果分组统计;

having子句用于限制分组显示结果;

(1)查询出每一个部门的平均工资和最高工资;

p_w_picpath

(2)查询出每一个部门的每种岗位的平均工资和最低工资;

p_w_picpath

(3)查询出平均工资低于2000的部门号和它的平均工资.

p_w_picpath

重点总结:

对数据分组的总结:

1.分组函数只能出如今选择列表、having、order by子句中;

2.若在select语句中同时包含有group by、having、order by则它们的顺序是group byhavingorder by;(先分组à再筛选à最后排序)

3.在选择列中若是有列、表达式和分组函数,那么这些列和表达式必须有一个出现group by子句中,不然会出错!

范例:

p_w_picpath

3-多表查询(重中之重!)

多表查询是基于两个和两个以上的表或视图的查询。

在实际应用中,查询单个表可能不知足要求,(例如: 查询出sales部门位置和其员工的姓名),这种状况下须要使用到(deptno表和emp表).

(1)查询出雇员名、雇员工资和所在部门的名字(笛卡尔积);

原则:多表查询的条件是:至少不能少于 表的个数-1

范例:查询出部门名(dname),员工名(ename)和薪水(sal)的信息

p_w_picpath

p_w_picpath

(2)查询出部门号为10的部门名、员工名和工资;

分析:

a)套路:

*由于有3个列(部门号为10部门名、员工名和工资)因此先用3个?(问号)代替之;

*2张表使用别名;

*找出2张表“纽带”;

*用实际列名代替3个?号。

范例:

p_w_picpath

p_w_picpath

p_w_picpath

p_w_picpath

上面把全部部门的都查询出来,可是咱们只要 “部门号为10”:

p_w_picpath

(3)查询出每一个员工的姓名、工资及其工资的级别。

p_w_picpath

p_w_picpath

p_w_picpath

扩展:

(4)查询出雇员、雇员工资及所在部门的名字,并按部门排序。

p_w_picpath

p_w_picpath

自链接:

是指在同一张表的链接查询。

(5)查询出某个员工的上级领导的姓名

分析:

No.1: 先看FORD –> MGR 7566(上级领导编号) –> EMPNO 7566(雇员编号) –> 雇员名字JONES

p_w_picpath

No.2: 咱们能够把同一张表emp表当作2张表(a一、a2)!

p_w_picpath

子句查询

*子查询:是指嵌入在其它sql语句中的select语句,也叫嵌套查询。

*单行子查询:是指只返回一行数据的子查询语句;

*多行子查询:是指返回多行数据的子查询。(四、5张已是很复杂了,不建议超过它!)

(6) 单行子查询:是指只返回一行数据的子查询语句;

范例:

查询出与SMITH同一部门的全部员工。

p_w_picpath

(7)多行子查询:是指返回多行数据的子查询。(四、5张已是很复杂了,不建议超过它!)

范例:

查询出与部门编号为10的工做岗位相同的雇员的名字、岗位、工资、部门号

p_w_picpath

(10)在多行子查询中使用all操做符

范例:all:含义是全部XXX!

查询出工资比部门编号30的全部员工的工资高的员工的姓名、工资和部门编号。

注释:查询出来的每条记录中的sal都应大于部门编号为30号中的员工薪水便可!

其实只要比最高的工资高便可)!

方法1:

p_w_picpath

方法2:效率高得多 比 方法1

232250651.jpg

(11)在多行子查询中使用any操做符

范例:any:含义是任意一个XXX!

查询出工资比部门编号是30的任意一个员工的工资高的员工的姓名、工资和部门编号。

注释:查询出来的工资只要比部门编号为30中任一个员工大(其实只要比最低的工资高便可),就能够了!

方法1:

p_w_picpath

方法2:效率高!

p_w_picpath

(12)多列子查询

*单行子查询是指子查询只返回单列单行数据;

*多行子查询是指返回单列多行数据,都是针对单列而言的,

*多列子查询则是指查询返回多个列数据的子查询语句。

范例:

查询出与SMITH的部门和岗位彻底相同的全部雇员。

p_w_picpath

范例:难度 ★★

查询出高于本身部门平均工资的员工的信息。

PS:

*给列起别名时,能够 as;

*给起别名时, as.

p_w_picpath

概括:from子句中使用子查询

当在from子句中使用子查询时,该子查询会被做为一个视图来对待,故叫内嵌视图

当在from子句中使用子查询时,必须给子句查询指定别名。

(13)分页查询

Oracle分页一共有3种方式:

方法:rownum分页:

范例:

按雇员的id号升序取出 8~12这5行!

No.1步: (select * from emp )看成是内嵌视图且起个别名a1,以下图所示:

p_w_picpath

No.2步: 显示rownum[Oracle分配的] (注:看成公式记住!)

p_w_picpath

注释:

* (select * from emp) a1表示: 给(select * from emp)起个别名为a1;

* rownum rn 表示:显示rownum(行号)且别名是rn;

* a1.* 表示: 将子查询(select * from emp)取出来,再查询1次.

No.3步: 取出/筛选/截取rn列小于等于12;

p_w_picpath

//将(select a1.*,rownum rn from (select * from emp) a1 where rownum<=12)看成内嵌视图(from子查询),再次查询之,以下图所示:

p_w_picpath

概括总结:

a. 若是指定查询列,则仅需修改最内层的子查询; (select * from emp)

范例: 查询出rn列,行号为8~12的雇员姓名、薪水的信息。

p_w_picpath

b.如何排序,仅需修改最内层的子查询;

范例:查询出rn列,行号为8~12的雇员姓名、薪水且按薪水的升序排列的信息。

p_w_picpath

范例:查询出rn列,行号为8~12的雇员姓名、薪水且按薪水的降序排列的信息。

p_w_picpath

c.查询出4~9

p_w_picpath

PS:

统计一张表(emp)总共有多少行?

p_w_picpath

(14)用查询结果建立新表

范例:在生产环境中,咱们不能对正在运行的表做增、删、改、查,则可用此方法建立一张新表(testemp),再在testemp表作测试!

p_w_picpath

(15)合并查询 注:实际工做中,用得不多!绝世高手才用!查询速度很是快!

在实际应用中,为了合并多个select语句的结果,可使用集合操做符unio、unio all、intersect、minus 。

1)union

用于取得2个结果集的并集。union会自动去掉结果中重复的行。

2)union all

用于取得2个结果集的并集。union all不会去掉结果中重复的行,并且不会排序。

3)intersect

用于取得2个结果集的交集

4)minus

用于取得2个结果集的差集。只显示在第1个集合中,而不存在第2个集合中的数据。

范例:union用于取得2个结果集的并集。union会自动去掉结果中重复的行.

p_w_picpath

范例:union all用于取得2个结果集的并集。union all不会去掉结果中重复的行,并且不会排序.

p_w_picpath

范例:intersect用于取得2个结果集的交集。

p_w_picpath

范例:minus用于取得2个结果集的差集。只显示在第1个集合中,而不存在第2个集合中的数据.

p_w_picpath

2-左、右链接

关于左、右链接指的是查询判断条件的参考方向,例如:有以下查询:

071933546.jpg

部门一共有4个,可是如今只返回3个部门的信息,缺乏40部门的信息,由于在雇员表中没有一条记录是属于40部门的,故如今不会显示40部门的信息。即:如今的查询是以emp表为参考,若是如今我非要显示40部门的信息呢?就必须改变参考方向,因而左、右链接就应运而生了!

范例:

072015204.jpg

如上图所示:40部门出现了!故发现参考方向改变了,而“(+)”就用于左、右链接的更改,此种符号有如下两种使用状况:

* (+)= :放在了等号的左边,表示的是右链接;

*=(+) : 放在了等号的右边,表示的是左链接

可是不必刻意的区分是左,仍是右,只是根据查询结果而定,若所须要的数据没有显示出来,就改变链接的方向便可。

范例:查询出每一个雇员的姓名和领导的姓名

072657638.jpg

由上图可知,此时的查询的结果少了1条记录,即缺乏了“KING”的记录,是由于KING没有上级领导,而想解决此问题须要使用左、右链接的问题了。

072825927.jpg

注:此种符号是Oracle数据库本身独有的,其余数据库不能使用!

3-SQL1999语法:

SQL语法之中,也提供了一套用于表链接的操做SQL,格式以下:

072942498.jpg

分解上面的多个语法:

1、交叉链接(CROSS JOIN):用于产生笛卡尔积;


SQL> SELECT * FROM emp CROSS JOIN dept;

笛卡尔积自己并非属于无用的内容,在某些状况下仍是须要使用的。

2、天然链接(NATURAL JOIN):自动找到匹配的关联字段,消除笛卡尔积;

073348508.jpg

可是并非全部的字段都是关联字段,设置关联字段须要经过约束指定。

3JOIN…USING子句:用户本身指定一个消除笛卡尔积的字段;

073453117.jpg

4JOIN…ON子句:用户本身指定一个能够消除笛卡尔积的关联条件;

073557493.jpg

5、链接方向的改变:

* ()链接:LEFT OUTER JOIN…ON

* ()链接:RIGHT OUTER JOIN…ON

* ()链接:FULL OUTER JOIN…ONà将两张表中没有的数据都显示出来。

范例:

073703694.jpg

没有40部门,咱们换成RIGHT JOIN…ON ,以下图所示:

073949376.jpg

由上可知:40部门出现了!

Oracle以外的数据库(SQLSERVERMYSQLDB2等)都使用以上的SQL1999语法操做,故必需要会!(固然,一直使用Oracle数据库,就能够不会:))

再次强调:多表查询的性能确定不高,并且性能必定要在大数据量的状况下,才能发现。

相关文章
相关标签/搜索