• oracle——外连接查询


    一、问题描述

      有时我们为了保留某个表中的数据,而该表中的数据在另外一个关联表中未必都存在对应,此时就应该试用外连接查询。

      比如:两个表,产品表和子产品表

    注:子产品的parent_product_id便是产品表的id

      产品可以有子产品,也可以没有子产品

      遇到类似的问题需要使用外连接查询,保证所有的产品被查询出来,而其对应的子产品也在查询结果中。

    二、问题解决

      1.基础概念

        笛卡尔积:例如,A={a,b}, B={0,1,2},则

             A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
             B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}

         即,一个集合在左和在右做“笛卡尔积”结果是不同的。

      2.外连接查询

        2.1左外连接查询

    select *
    from table_a a left join table_b b
    on a.id = b.parent_id

    这样的结果就是左边的表中的内容都会被保留,而右边表每条数据会对应左边表中对应的数据,结果中,右边表中的所有内容只出现一次(table_a和table_b是一对多关系,且table_b中记录只对应一个table_a中记录),而左边表中一条记录可能显示多次。

    e.g.

    select pp.product_id,pp.product_name,p.product_id,p.product_name
    from edu_product pp--产品
    left join sub_edu_product p--子产品
    on pp.product_id = p.parent_product_id;

        2.2右外连接

    select *
    from table_a a right join table_b b
    on a.id = b.parent_id

    这样的结果就是右边的表中的内容都会被保留,而右边表每条数据会对应左边表中对应的数据,结果中,右边表中的所有内容只出现一次(table_a和table_b是一对多关系,且table_b中记录只对应一个table_a中记录),而左边表中一条记录可能显示多次。和左外连接的区别是,左表不会保留多出来的数据

    e.g.

    select pp.product_id,pp.product_name,p.product_id,p.product_name
    from edu_product pp--产品
    right join sub_edu_product p--子产品
    on pp.product_id = p.parent_product_id;

     三、补充

      试用外连接查询时有时会有一些疑问,总结在下面:

      试用oracle中emp和dept表做示例

    dept:

    emp:

    1.相同的左外连接查询得到不同的展示结果

    select dept.deptno,dept.dname,
              emp.ename,emp.empno
    from dept left join emp
    on dept.deptno = emp.deptno;

    select emp.ename,emp.empno,
              dept.deptno,dept.dname
    from dept left join emp
    on dept.deptno = emp.deptno;

    结论:红色部分完全相同,说明外连接方向及条件一样,区别在查询的字段排序不同,导致结果不同。

       而第二种结果不能代表此次查询是右外连接

    2.on条件上等号左右字段颠倒,效果是否相同

    select dept.deptno,dept.dname,
              emp.ename,emp.empno
    from dept left join emp
    on dept.deptno = emp.deptno;

    select dept.deptno,dept.dname,
              emp.ename,emp.empno
    from dept left join emp
    on  emp.deptno = dept.deptno;

    结论:对比结果发现,没有任何区别

    3.使用+号进行外连接查询

    select *
    from (select e.empno,e.ename,d.deptno,d.dname
    from emp e,dept d
    where e.deptno = d.deptno) s, emp_dept ed
    where ed.empno(+) = s.empno;

      emp_dept表中存放了emp,dept连接查询的部分结果。所以,s表包含了ed表中的所有内容

      +放置的位置:哪面少哪面用+号,或者说哪面可能出现空记录,哪面用+号

  • 相关阅读:
    生活感悟(一)
    DOM数据制作(采用卫星遥感图像数据制作)
    对话框显示前的操作
    sqlHelper中DataReader的关闭问题
    整数的取余运算
    C#中的字符串格式String.Format
    SQL分页查询
    级联删除与更新的例子
    C#中的运算符重载(以重载+为例)
    [高效编程读书笔记]用readonly而不是const
  • 原文地址:https://www.cnblogs.com/brolanda/p/4689118.html
Copyright © 2020-2023  润新知