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;

    均可以得到下面的结果:

  • 相关阅读:
    jsp 特殊标签
    poj 1753 Flip Game 高斯消元 异或方程组 求最值
    zoj 3155 Street Lamp 高斯消元 异或方程组 求方案数
    poj1222 EXTENDED LIGHTS OUT 高斯消元解异或方程组 模板
    zoj 3930 Dice Notation 模拟
    zoj 3157 Weapon 线段树求逆序对数
    hdu 1242 Rescue BFS+优先队列
    hdu 3466 Proud Merchants 贪心+01背包
    zoj 3689 Digging 贪心+01背包
    hdu 2602 Bone Collector 01背包模板
  • 原文地址:https://www.cnblogs.com/damonlan/p/2635350.html
Copyright © 2011-2022 走看看