zoukankan      html  css  js  c++  java
  • 表连接


    1.表连接
    //>>> Ⅰ.不同数据表之间的连接
    (1)内连接(inner join)
    内连接组合两张表,并且基于两张表中的关联关系来连接它们。使用内连接需要指定表中哪些字段组成关联关系,并且需要指定基于什么条件进行连接。
    内连接要求组成连接的两个表必须具有匹配的记录。(无法匹配NULL值的记录)
    语法:
    inner join table_name
    on condition ;
    举例: 检索所有的客户姓名为mike的客户的订单号及价格
    SELECT FNumber ,FPrice FROM t_order
    INNER JOIN t_customer
    ON FCustomerId=t_customer.FId
    WHERE t_customer.FName='mike';
    注意:
    在大多数数据库系统中,inner join 中的inner是可选的。inner join是默认的连接方式
    为了避免列名的歧义,建议使用表连接的时候要显示字段所属的表。
    (2)不等值连接
    处理等值连接,还存在另一种不等值连接。在连接的条件中可以使用小于,大于,不等于等运算符,而且可以使用Like ,between and 等运算符,甚至可以使用函数。

    如:需要检索价格小于每个客户年龄的5倍值的订单列表,那么就可以使用不等值连接:
    SELECT t_order.`FNumber`,t_order.`FPrice`,t_order.`FCustomerId`
    ,t_customer.`FName`,t_customer.`FAge`
    FROM t_order
    NNER JOIN t_customer
    ON t_order.`FPrice`<t_customer.`FAge`*5;
    //>>>说明:
    不等值连接产生大量的查询结果,因为它是对被连接的两张表做笛卡尔积运算。
     //>>>解决方案:
    如果想查看客户对应的订单,那么就要在不等值连接后添加等值连接匹配条件
    SELECT t_order.`FNumber`,t_order.`FPrice`,t_order.`FCustomerId`
    ,t_customer.`FName`,t_customer.`FAge`
    FROM t_order
    NNER JOIN t_customer
    ON t_order.`FPrice`<t_customer.`FAge`*5
    AND t_order.`FCustomerId`=t_customer.`FId`;---等值连接匹配条件清除重复
    (3)交叉连接
    与内连接比起来,交叉连接非常简单。因为它不存在on子句。
    交叉连接会将涉及到的所有表中的所有记录都包含在结果集中。
    1.隐式方式定义交叉连接 --->>只要在select 语句中的from语句后将要进行交叉连接的表名列出即可。(可以使用表的别名)
    举例:将t_customer表和t_order表做交叉连接
    SELECT * FROM t_order , t_customer
    2.显示方式定义交叉连接--->>>使用cross join 关键字,语法类似inner join
    SELECT t_order.`FNumber`,t_order.`FPrice`,t_order.`FCustomerId`
    ,t_customer.`FName`,t_customer.`FAge`
    FROM t_order
    CROSS JOIN t_customer
    注意: cross join的声明方式只能被mysql ,MSSQLServer ,oracle所支持,db2不支持。
    但隐式交叉连接所有数据库都支持。

    (4)自连接 //>>>Ⅱ.同一张表直接的连接
    自连接不是独立于前几种连接方式的。它只是那几种连接方式中的一种特例。也就是说,交叉连接,内连接,不等值连接用在同一张表就称为自连接。
    举例:需要检索与另外一个订单的订单类型一样的所有订单的列表。
    错误写法1:
    SELECT FNumber ,FPrice ,FTypeId
    FROM t_order
    WHERE FTypeId=FTypeId;
    错误分析:这里where语句条件永远为真,因为同行的相同列总是等于自己。因此结果集中将包含表中的所有记录。
    解决方案: 假象存在另一个t_order表与t_order表完全相同的表,然后我们就可以在这两张表中进行任意的连接了。(需区分这两张表,使用表的别名)
    //这里使用inner join进行连接如下: --->>>仍然存在一点问题???
    SELECT o1.FNumber ,o1.FPrice ,o1.FTypeId,
    o2.FNumber ,o2.FPrice ,o2.FTypeId
    FROM t_order o1
    INNER JOIN t_order o2
    ON o1.FTypeId=o2.FTypeId;
    //为t_order表取了两个别名o1,o2;
    问题:存在‘A匹配B,B匹配A’的问题。如自己与自己的订单类型必定相同
    解决方案:我们这里真正要查询的是具有相同的FTypedId字段值的两个不同的订单,因此需加个条件:and o1.FId=o2.FId;
    最终正确的sql语句是:
    SELECT o1.FNumber ,o1.FPrice ,o1.FTypeId,
    o2.FNumber AS O2_FNumber ,o2.FPrice AS O2_FPrice ,o2.FTypeId AS o2_FTypeId
    FROM t_order o1
    INNER JOIN t_order o2
    ON o1.FTypeId=o2.FTypeId
    AND o1.FId<>o2.FId;
    (5)外部连接--->主要用来解决空值匹配问题
    语法与内部连接几乎一致,主要区别就是对空值的处理。。外部连接不需要两个表具有匹配记录,这样就可以指定给某个表中的记录总是放到结果集中。
    根据哪个表的记录总是放在结果集中,外部连接分为三种类型:
    类型一:右外部连接(RIGHT OUTER JOIN)
    类型二:左外部连接(LEFT OUTER JOIN)
    类型三:全外连接(FULL OUTER JOIN)
    三者共同点: 都返回符合连接条件的数据,这一点和内部连接是一样的。
    不同点:
    ◆左外部连接还返回左表中不符合条件是数据
    ◆右外部连接还返回右表中不符合条件是数据
    ◆全外部连接将返回左表中和右表中不符合条件的数据,是左外部连接和右外部连接的集合。
    注意:这里的左表右表是相对join关键字来说的,在join关键字左侧的称为左表,右侧称为右表。
    如:
    SELECT o1.FNumber ,o1.FPrice ,o1.FTypeId,
    o2.FNumber AS O2_FNumber ,o2.FPrice AS O2_FPrice ,o2.FTypeId AS o2_FTypeId
    FROM t_order o1
    INNER JOIN t_order o2
    ON o1.FTypeId=o2.FTypeId
    AND o1.FId<>o2.FId;
    左表:o1
    右表:o2


















  • 相关阅读:
    昨晚睡不着觉,测这周运气
    老大让我看baidu他们的查公交是怎么做的,我就看了
    破逼Json,该死的Json库,操了
    我真的好累,实在不知道该怎么办了
    今晚刚回家,给人算了一卦运气
    bzoj4590[Shoi2015]自动刷题机
    bzoj4552[Tjoi2016&Heoi2016]排序
    bzoj3155Preprefix sum
    bzoj2463[中山市选2009]谁能赢呢?
    bzoj3668[Noi2014]起床困难综合症
  • 原文地址:https://www.cnblogs.com/xiaowei-blog/p/3952276.html
Copyright © 2011-2022 走看看