INTERSECT表示交运算,它返回两个查询中都返回的行。
MINUS表示差算,它返回前一查询返回而后一查询没有返回的行。 例27:列出\部门和\部门中的所有职务: SELECT DISTINCT job FROM people WHERE deptcode='P20' UNION
SELECT DISTINCT job FROM people WHERE deptcode='P30'; 结果为:
办事员 采购员 处长 推销员 例28:列出职务是处长或科长但又不在\部门中的所有人员: (SELECT * FROM people WHERE job='处长' UNION
SELECT * FROM people WHERE job='科长') MINUS
SELECT * FROM people WHERE deptcode='P40'; 结果为: 3 周金海 男 45/08/21 81/10/20 处长 170 P10 4 陈宝娟 女 51/06/17 85/07/12 科长 150 P11 6 顾为民 男 55/10/01 84/06/11 科长 160 P12 9 郑文华 男 56/06/20 85/04/22 科长 150 P13 12 沈晓华 男 53/09/28 82/12/15 处长 180 P20 17 赵汉雄 男 45/05/13 83/02/18 处长 170 P30 26 黄伯尧 男 50/10/18 85/08/23 处长 180 P50 当然,上面两个例子可以不用查询的交、并、差运算,而可简单地表示为: WHERE deptcode='P20' OR deptcode='P30' 和
WHERE job in('处长','科长') AND deptcode !='P40'
但是,如果两个查询引用的是不同的表,则就只有使用并、交、差运算了。 另外,对查询的并、交、差运算有下面的一些限制: * 两个查询必须取相同数量的列;
* 两个查询中对应列必须是同样的数据类型(长度可以不同); * 两个查询中对应列的列名或别名必须相同; * 查询中不可引用类型为LONG的任何列;
* ORDER BY子句只能在查询末尾使用一次,而不能在每个查询后面都使用。 (三) 表的连接和多表同时查询
1、表连接的概念
查询所牵涉到的数据有时可能不是存贮在单个表中 ,而是存贮于两个或多个表中,这时就必须按照某种规则把需要选取数据的表连接起来进行查询,这种查询叫连接查询。连接查询是通过各表中相应列的公共数据把一个表中的某些行与另一个表中的某些行连接起来。例
如,若想知道职工沈晓华的工作地点。在people表中并没有有关工作人员办公地点的列,而只有工作人员的工作部门列,但是在department 表中却有部门地址的列。所以我们可以先从people表中找出沈晓华在P20部门工作,再观察 department表就可以知道,P20部门的地址是在公司大楼203室。
在这里使用了两表中deptcode列的公共数据把PEOPLE表中的一行与department表中的一行连接了起来(如下所示)。
连接列 ↓ P20 ??公司大楼203室?? ??沈晓华??
2、如何规定连接列
在一个查询中,若要连接两个表时,必须规定连接列,此列含有两个连接表相应的信息。例如people表中的deptcode和department表中的deptcode。具体地说,应该在SELECT命令的FROM句中规定的连接的表,在WHERE子句中规定连接的列和连接的方式。 形式如下:
SELECT 列1,列2, ...... FROM 表1,表2, ......
WHERE 连接条件和行选择条件;
注意:各个表名必须用逗号隔开。连接条件规定了连接的列和连接方式,它也是一个逻辑表达式。
在这儿可以看到WHERE子句既可用来规定行选择条件;又可用来规定连接条件(连接列和连接方式)。如果在WHERE子句中同时使用了这两种条件的话,则应该把这两种条件的逻辑表达式用and连接,所以总的说来WHERE子句的后面还是一个逻辑表达式。 例29:找出职工沈晓华的工作地点: SELECT peopname,address FROM people,department WHERE peopname='沈晓华'
and people.deptcode=department.deptcode; 结果为:
沈晓华 公司大楼203室 从这里还可以看到,连接条件的连接列前部冠以了表名,这是因为在这两个表中的列名是相同的。当两个表中的连接列的名字相同时,必须在连接列前冠以表名,以表示究竟是哪个表的列。如果在查询中两个表的列名都是唯一的,就不必在列名前冠以表名了,这个规定同样也适用于其它引用列名的子句(如SELECT子句、ORDER BY子句等)。
3、使用表名的别名
像列名能使用别名一样,FROM子句中的表名也可以使用别名, 使用的规则也是在表名后加一个空格,而后立即跟随表的别名。
例30:列出在公司大楼101室工作的所有人员: SELECT peopname,job,d.deptcode,deptname FROM department d,people p
WHERE address='公司大楼 101室' and d.deptcode=p.deptcode; 结果为:
P13 财务处报销科 郑文华 科长 罗四明 报销员 P13 财务处报销科 张明君 报销员 P13 财务处报销科 表的别名有如下的一些用途:
* 简化输入(特别当表名很长时);
* 当表要与自身连接时(下面就会讲到); * 在相关子查询中(下一节将会讲到)。
4、表与自身的连接
当需要把表中的某些行与同一表中的另一些行连接时,就必须要把表与其自身连接起来。表与自身的连接必须使用表的别名,若在FROM子句中用两个不同的别名对应于同一个表时,就可以像连接两个分开的表一样来把表与自身连接起来。 例31:列出财务处的下属部门:
SELECT lowdept.deptcode,lowdept.deptname, updept.deptname FROM department lowdept, department updept WHERE updept.deptname='财务处' and lowdept.higher=updept.deptcode; 结果为: P11 财务处计划科 财务处 P13 财务处报销科 财务处 P12 财务处记帐科 财务处 例32:列出工资大于\赵汉雄\工资的所有人员: SElECT x.peopname,x.salary,x.job FROM people x,people y WHERE y.peopname='赵汉雄' and x.salary>y.salary; 结果为:
李铭棠 200 经理 沈晓华 180 处长 王英泉 210 处长 黄伯尧 180 处长 沈妙玉 180 驾驶员 从这个例子中还可以看到:表连接不一定是等值连接,它也可以是不等值连接。
5、外连接
一般来说,如果某一表中所选取的一行不能与另一个表中的任何一行相连接(即不满足连接条件)时,则在查询结果中此行不再出现。
例33:列出P30和P10部门的人员和工作地址,
SELECT d.deptcode, deptname, peopname, job, address FROM department d, people p
WHERE d.deptcode in ('P30', 'P31') and d.deptcode=p.deptcode; 结果为: P30 销售处 赵汉雄 处长 公司大楼204室 P30 销售处 姚国平 推销员 公司大楼204室 P30 销售处 张宗恒 推销员 公司大楼204室 P30 销售处 曹向群 推销员 公司大楼204室 P30 销售处 王晨 推销员 公司大楼204室 P30 销售处 史玲娟 办事员 公司大楼204室 在这里可以看到,由于P31部门没有人员,它不能与people表相连接,所以连P31部门的编号,名称和地址信息也不显示了,有时可能会造成不存在P31部门的假象。 如果要求即使没有匹配的人员,也要把部门的信息显示出来的话, 就需要使用外连接。
连接是通过连接条件中的某个连接列后面加一个外连接操作符(+)来实现的,例34:用连接列出P30和P31部门的人员和工作地址:
SELECT d.deptcode, deptname, peopname, job, address FROM department d, people p WHERE d.deptcode in ('P30','P31') and d.deptcode=p.deptcode(+); 结果为: P30 销售处 赵汉雄 处长 公司大楼204室 P30 销售处 姚国平 推销员 公司大楼204室 P30 销售处 张宗恒 推销员 公司大楼204室 P30 销售处 曹向群 推销员 公司大楼204室 P30 销售处 王晨 推销员 公司大楼204室 P30 销售处 史玲娟 办事员 公司大楼204室 P31 销售研究中心 公司大楼202室 此例的WHERE子句中连接表达式中的p.deptcode后面使用了外连接符号,SQL在处理时,对people表添加了一个各列全为空值的额外行,若depoctment表中的行不能与people表中任何一行连接,则与这个额外行连接,以保证depoctment表中各行的信息在查询结果中显示出来。
在结束这部分内容之前,再来看一个使用外连接的例子。 例35:列出那些没有人员的部门.
SELECT deptcode, d.deptname, address, peopname FROM department d, people p WHERE d.deptcode=p.deptcode(+) and peopname is null; 结果为:
P31 销售研究中心 公司大楼202室 (四) 子查询的使用
SQL还可以使用嵌套查询,所谓嵌套查询是在 WHERE 子句中包含另一个查询,WHERE子句中的这个查询就称为子查询。
在WHERE子句中的逻辑表达式中, 子查询必须用在关系表达式的右侧,并由一对括号括起来。子查询返回的值可以是一个值或一列值,甚至多列值,这些值成为关系表达式中的一部分,最后形成主查询的检索条件。
一般来说,若查询条件依赖于表中的数据, 即查询条件可以动态变化时,用子查询是很合适的。
1、返回一个值的子查询
返回一个值的子查询是最简单的子查询,由子查询返回的值,就是WHERE子句中逻辑表达式的一个值。
例如:要找出工资高于赵汉雄的工资的所有人员,在找出这些人员之前,需要先找出赵汉雄的工资,然后再把每个人员的工资与赵汉雄的工资进行比较, 以找出满足条件的人员。当然要解决这个问题,可以通过两次查询:
SELECT salary FROM people WHERE peopname='赵汉雄'; 得到结果为170。然后:
SELECT peopname,salary FROM people WHERE salary> 170; 结果为:
李铭棠 200 沈晓华 180 王英泉 210 黄伯尧 180 沈妙玉 180 但是,若在WHERE子句中使用子查询找出赵汉雄的工资,就可以通过一次查询得到同样的结果:
SELECT peopname,salary FROM people WHERE salary> (SELECT salary FROM pople WHERE peopname='赵汉雄');
当这里,SQL*Plus将先执行用括号括起来的子查询,该子查询返回赵汉雄的工资,主查询再把每个人的工资与返回值比较,以决定是否选取该行。按这种方式使用子查询,如果没有返回值或返回值多于一个,则SQL*Plus将给出错误信息。
2、返回一组值的子查询
如果子查询返回多个值,则必须规定返回值在WHERE子句中的使用方式,此时在关系运算符(=、!=、>、>=、<、<=)与子查询之间应插入any或all,若插入any,则只要有一个返回值使关系表达式成立,查询条件就满足。若插入all,则要所有返回值都使关系表达式成立,查询条件才满足。其中=any可用in代替、!=all可用not in代替。 下面我们来看几个返回多个值的子查询的例子:
例36:列出工资比P00部门中最低工资高的其它部门中全部职工的情况 SELECT peopname,salary,job,deptcode FROM people
WHERE salary > any(SELECT salary FROM people WHERE deptcode='P00') and deptcode != 'P00'; 结果为:
P10 周金海 170 处长 P12 顾为民 160 科长 P20 沈晓华 180 处长 P30 赵汉雄 170 处长 P40 王英泉 210 处长 P50 黄伯尧 180 处长 沈妙玉 180 驾驶员 P50 黄金宝 170 驾驶员 P50 例37:列出工资高于P00部门最高工资的全部职工的情况 SELECT peopname,salary,job,deptcode FROM people
WHERE salary > all(SELECT salary FROM people WHERE deptcode='P00';
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库资料 SQL语言(3)在线全文阅读。
相关推荐: