Oracle数据库笔记三(连接查询:自连接、外连接、)
连接查询
连接是关系数据库模型的主要特点。当两个或多个表中存在相同意义的字段时,便可以通过这些字段对不同的表进行连接查询。
因为fruits表和suppliers表中有相同的字段s_id,因此在比较的时候需要完全限定表名(格式为“ 表名.列名” 【中间是点号】),如果只给出s_id,Oracle将不知道指的是哪一个。并返回错误信息
select suppliers.id,s_name,f_name,f_price from fruits,suppliers where fruits.id=suppliers.id; (两个表含有相同的s_id,所以s_id需要使用 表名.列名 的形式,如果为一个表中独有的字段,如s_name,f_name,f_price字段,则不需要,直接写字段名就行)
自连接查询
如果在一个连接查询中,涉及的两个表都是同一个表,这种查询称为自连接查询。自连接查询是一种特殊的内连接。
--查询f_id=a1的水果供应商提供的其它水果 select f1.f_id,f1.f_name from fruits f1,fruits f2 where f1.sid=f2.s_id and f2.f_id='a1'; --where f1.sid=f2.s_id and f2.f_id='a1'可以得出s_id=101 下面语句与自连接效果相同 select f_id,f_name from fruits where s_id=(select s_id from fruits where f_id='a1'); 或者 select f_id,f_name from fruits where s_id in (select s_id from fruits where f_id='a1');
外连接(左(外)连接、右(外)连接、全(外)连接)
1、左连接 LEFT JOIN
左连接的结果包括 left outer join (其中outer可以省略不写)子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在表中没有匹配行,则在相关的结果行中,右表的所有选择列均为空值。
--在customers表和orders表中,查询所有客户,包括没有订单的客户(left outer join中outer可以省略不写,)
select customers.c_id,orders.o_num from customers left outer join orders on customers.c_id=orders.c_id; --其中customers.c_id=10002没有对应的订单,所以为null
(左表) (右表)
2、右连接 RIGHT JOIN
右连接是左连接的反向连接,将返回右表的所有行,如果右表的某行在左表中没有匹配的行,左表将返回空值。
--在customers表和orders表中,查询所有订单,包括没有客户的订单 select order.c_id,customers.c_name from customers right outer join orders on customers.c_id=orders.c_id; --其中orders表中c_id=10005没有对应的客户,所以为null
3、全外连接 FULL JOIN
返回左右表中所有的记录和左右表中连接字段相等的记录
内连接(等值连接 inner join)
只返回两个表中连接字段相等的行
带ANY、SOME、all、exists、in关键字的子查询
1、any、some关键字是同义词,表示满足其中任意条件
2、all关键字与any和some不同,使用all时需要同时满足所有内层查询的条件。
--tbl1中num1列的某个值比tbl2中num2列的任意一个数大就行 select num1 from tbl1 where num1>any(select num2 from tabl2); --tbl1中num1的某个值比num2列的所有值都大 select num1 from tbl1 where num1>all(select num2 from tabl2);
3、exists关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,那么exists的结果为true,此时外层查询语句将进行查询;
如果子查询没有返回任何行,那么exists返回的结果是false,此时外层语句将不进行查询
--查询suppliers表中是否存在s_id=107的供应商,如果存在,则查询fruits表中的记录 select * from fruits where exists (select s_name from suppliers where s_id=107); --查询suppliers表中是否存在s_id=107的供应商,如果存在,则查询fruits表中f_price>10.2的记录 select * from fruits where f_price>10.2 and exists (select s_name from suppliers where s_id=107);
not exists与exists使用方法相同,返回的结果相反
exists和not exists的结果只取决于是否会返回行,而不取决于这些行的内容,所以这个子查询输入列表通常是无关紧要的
执行子查询时,Oracle实际上执行了两个操作过程,即先执行内层子查询,再执行外层查询,内层子查询的结果作为外部查询的比较条件
4、IN
--在orderitems表中查询f_id为c0的订单号,并根据订单号查询orders表具有订单号的客户c_id select c_id from orders where o_num in (select o_num from orderitems where f_id='c0');
IN关键字进行查询时,内层查询语句仅仅返回一个数据列,这个数据列里的值将提供给外层查询语句进行比较操作
还有NOT IN:返回不在条件范围的值。
带比较运算符的子查询
比较运算符:<、 <=、 =、 >=、 >等符号,不等于"<>"或"!="运算符
--在suppliers表中查询s_city等于‘Tianjin’的供应商s_id,然后在fruits表中查询所有该供应商提供的水果种类 select f_name from fruits where s_id =(select s1.s_id from suppliers s1 where s1.s_city='Tianjin')
合并查询结果
利用union关键字,可以给出多条select语句,并将他们的结果组合成单个结果集。
合并时,两个表对应的列数和数据类型必须相同,各个select语句之间使用union或union all关键字分隔。
union不使用关键字all,执行的时候删除重复的记录,所有返回行都是唯一的;
使用关键字all的作用是不删除重复行也不对结果进行自动排序。
--查询所有价格小于9的水果信息,查询s_id=101和s_id=103所有的水果的信息,说用union连接查询的结果 select s_id,f_name,f_price from fruits where f_price<9 union all select s_id,f_name,f_price from fruits where s_id in(101,103);
视图