zoukankan      html  css  js  c++  java
  • 跟我一起学Oracle 11g【8】SQL 基础学习2[连接查询]

    前言

    前面的查询主要都是针对一个表而言的。但是,在我们项目现实中,有更多的是多个表联合起来查询。所以,若一个查询同时涉及2个以上的表,那么我们就叫它为连接查询。连接查询是数据库中最重要的查询,主要包括等值连接查询、自然连接查询、非等值连接查询,自身连接查询、外连接查询和复合条件查询。

    一。连接查询

    1.1等值与非等值查询

    连接查询的where字句总用来连接2个表的条件称为连接条件或者连接谓词。格式如下:

    [<表名>.] <列名> <比较运算符> [<表名>.] <列名>

    其中比如运算符有:等于(=)、大于(>)、小于(<)、大于等于(>=)、小于等于(<=)、不等于(用!=或者用<>都可以)等。

    连接条件我们还可以使用我们在上面一张提到过的 between....and的形式:

    [<表名>] <列名> between [表名] <列名> and[表名] <列名>

    使用“=”叫等值连接,其他则称为非等值连接。

    【例子1】查询每个学生及其选修课的情况

    我们在select字句中加上了表名,这样是为了防止混淆。如果属性名在参加连接的各表中是唯一的,则可以省略表名前缀。因为在我们的student表和course表均有sno,所以就不能省略咯。

    我们也可以使用as 为表指定别名。

    当然,我们这里使用表的别名的效果不太明显,如果在多张表连接起来的时候,使用通俗易懂的表名对我们有很大的帮助。

    如果在等值连接中,把目标列中重复的属性列去掉则为自然连接。

    【例子2】用自然连接重现例子1

    因为sno在2个表都有,所以需要指定表名前缀,而其余的由于不冲突,所以可以不用。

    1.2自连接

    连接不仅可以再2个表中进行连接,而且还可以一个表自己和自己进行连接。

    自连接主要是用来显示上下级关系或者层次关系的,

    【例子3】查询每一门课的简介先修课(也就是先修课的先修课)

    因为早course表中,只有每门课的直接先修课,而没有先修课的先修课。要得到这个信息,就必须先对一门课找到其先修课,在按照此先修课的课程号,查找它的先修课。

    我们定义了2个表,first表和second表,

    这里可能有点绕,需要好好琢磨琢磨这里。

    自连接我在一个oracl数据自带的一个例子,可能比较更好的理解。在Oracle中有一个表叫emp(conn scott/tirger),emp表里有一个列叫mgr,他是每个员工管理者的员工号,如果员工没有管理者则mgr为空。(比如在公司里,员工都属于某个经理,经理属于老板,而老板上面没有人了就为空。)

    OK,那我们现在需要找出谁是谁的manger,什么意思呢?我现在要找比如blake和clark的老板是king。。

    select m.ename || ' is ' || n.ename || ' Manger'
    from emp m,emp n
    where n.mgr=m.empno;

    结果如下:

    这里找出了谁是谁的manger,用的就是自连接。

    1.3外连接

    OK,我们现在在学生表Student中加入一条数据:

    insert into student values(005,'XiaoZhang','Male',18,'IS');

    然后,我们在【例子2】去查:

    我们没有找出XiaoZhang这个人。因为XiaoZhang这个人没有选课,所以它的数据就被抛弃了。但是,我现在想要全部学生的信息,不管他有没有选课呢?那怎么办呢?这个时候,我们就需要使用外连接了。

    外连接,分为左外连接、右外连接以及全连接

    左外连接:不仅会返回连接表中满足连接条件的所有语句,而且还会返回不满足连接条件的连接符左边表的其他行。(比如例子4)

    右外连接:不仅会返回连接表中满足连接条件的所有语句,而且还会返回不满足连接条件的连接符右1边表的其他行

    全连接:列出所有表的值。

    【例子4】重现【例子1】查询每个学生及其选修课的情况

    因为用的是左外连接,所以把左边表student的值全部显示出来,而不用管它有没有选课。

    右外连接也是一样,语句如下:

     select student.sno,sname,ssex,sage,sdept,cno,grade 
    from student righ outer join sc on(student.sno=sc.sno);

    全连接语法:

    select student.sno,sname,ssex,sage,sdept,cno,grade 

    from student inner join sc on(student.sno=sc.sno);

    另外一种写法:

    在oracle中,对左外连接和右外连接还有另外一种写法:

    左外连接是:左条件 = 右条件(+)

    右外连接是:左条件(+) = 右条件

    比如,我们现在的例子,我们只需要这样也可以得到一样的结果:

    select student.sno,sname,ssex,sage,sdept,cno,grade 
    from student,sc
    where student.sno=sc.sno(+);

    结构也是一样的哦!。

    Oracle 建议你用from语句后加Outer Join语法,而不是Oracle的Join操作符(+).而且(+)是要受下面的规则限制的,但Outer Join语法则不受。

    • 你不可以 在查询块中使用(+) 当它同时包含 join的from语句中
    • (+)只是在where语句中,并且只能对应一个表或视图的一行字段
    • 如果A和B做联接时有多个条件,那么(+)必须完善所有的匹配条件,
      如果没有 ,oracle不会警告你~只是结果自然不同的
    • 不 可以在作出一个表外查询 另张表内查询的(+)联接操作
    • 不可以用(+)外联接到自己 当然Self Join是可以的
    • 含 (+)的Where后的注意
      OR不可用
      IN不可用
      子查询不可用

    我们这里也在举一个oracle数据库自带的例子。有2个表emp表(员工表)和dept表(部门表) 每一个员工属于不同的部门中。

    左外连接:

    select d.dname,e.ename
    from emp e left outer join dept d on(e.deptno=d.deptno);
    当然也可以这样写:
    select d.dname,e.ename from emp e,dept d where e.deptno=d.deptno(+);

    列出了所有左边列emp的员工名字(ename)。

    右外连接:

    1.4复合条件连接

    所谓的复合条件查询,在where子句中可以有多个连接条件。

    【例子5】查询选修课为2号课程并且成绩在90分以下的同学

    select student.sno,sname,grade 
    from student,sc where sc.sno=student.sno --连接谓词,需要先对表进行连接
    and sc.Cno=2 and SC.Grade<=90; ---其他的限定条件

    结果如下:

    二。算数运算

    当我们在执行查询的时候,我们也可以再数字列使用算术表达式(+,-,*,/)。其中,乘和除的优先级要高于加减。

    【例6】为了应付上面的检查,现在需要把分数小于80分的人,加上20分。

    select sname,grade+20 from student,sc 
    where student.sno=sc.sno and grade<80;

    结果如下:

    三。集合查询

    本来这部分应该放到下一章节里讲的,可是因为嵌套查询的内容比较多,所以就提前讲的,里面的一些嵌套内容大家先了解下。

    select语句的查询结果是元组的集合,所有多个select语句的结构可以进行集合操作。

    集合操作包括并操作Union、交操作Intersect、差操作except。需要特别注意的是,参加集合操作的各查询结果的列数必须相同;对应的数据类型也必须相同。

    把这些和数学上的交集、并集以及差集就很好理解了。

    3.1并操作Union

    也就是or操作,把符合条件的列都列出来。

    【例7】查询计算机系的学生以及年龄不大于20岁的学生

    select *
    from student
    where sdept='CS'
    Union
    select *
    from Student
    where sage<20;

    等价于:

     select * from student where sdept='CS' or sage<20;

    结果如下:

    使用Union将多个查询结果合并起来,系统会自动去除重复元组,如果要保留重复元组则要用Union All操作符。

    3.2交操作Interact

    【例7】查询计算机系的学生以及年龄不大于20岁的学生的交集

    select *
    from student
    where sdept='CS'
    Intersect
    select *
    from Student
    where sage<20;

    也就是等价于:

    select * from student where sdept='CS' and sage<20;

    结果如下:

    【例8】查询既选修课程1又选修课程2的学生。

    select sno from sc where cno=1 

    intersect

    select sno from sc where cno=2;

    也就是:

    select Sno
    from sc
    where cno=1 and Sno in(
                 select Sno
                 from sc
                 where cno=2); ---这个表达式会在下面一章节中介绍。

    3.3差集except

    【例9】查询计算机系的学生以及年龄不大于20岁的学生的差集

    select * from student where sdept='CS'
    minus
    select * from student where sage<20;

    要记得的是不大于。等价于下面的SQL语句:

    select *
    from student 
    where sdept='CS' and sage>20;

    均可以得到下面的结果:

  • 相关阅读:
    #{}和${}的区别
    Shiro 的优点
    SpringSecurity 和 Shiro的之间的比较
    shiro的组件
    Apache Shiro 的三大核心组件
    Maven的工程类型有哪些?
    Maven仓库是什么
    什么是Maven?
    shiro有哪些组件?
    Apache Shiro 的三大核心组件
  • 原文地址:https://www.cnblogs.com/damonlan/p/2635350.html
Copyright © 2011-2022 走看看