连接查询

作者: Hughman | 来源:发表于2017-02-12 20:54 被阅读61次
    1.png

    join

    1、作用:

    每个实体,一个表,一个业务逻辑,使用多个实体的数据,多张表应该在一起使用,将多个表的记录连接起来。

    2、总体思路:

    先将所有的数据,按照某种条件连接起来,再进行筛选处理。

    3、概念:

    1)内连接:

    只有在连接的表内数据都存在的情况下,才会做连接。inner join

    2)交叉连接(笛卡儿积):

    内连接是可以省略连接条件的,意味着所有的左表的数据,都要和右表的记录做一个连接。共存在M*N个连接,这种连接就称之为交叉连接,或者笛卡儿积连接。两个二维表的没有条件的内连接就是笛卡尔积。也叫做交叉连结(cross join)
      笛卡尔积(cartesian product),又叫直积,所有可能的组合。假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。

    注意:

    mysql中cross join与inner join相同,但在数据库的定义上,交叉连接就是笛卡儿积,是没有条件的inner join。mysql中inner join是默认的连接方式,可以省略inner。

    3)有条件的内链接:

    会在连接时过滤非法的连接;
      where的写法:数据过滤,数据安装交叉连接完成后,再做数据过滤,
      on的写法:在连接时,就对数据进行判断。
      using的写法:using要求,负责连接的两个实体之间的字段名称一致。

    4)外连接:

    如果存在不能匹配的数据,也会进行连接,不过此时mysql会帮我们虚拟一条不存在的记录(字段值都是null),帮助我们完善整条连接记录。Mysql暂时不支持全外连接。
      自然连接:mysql自己判断连接条件,自动连接。支持内自然连接和外自然连接。但mysql的实现相对简单,自然连接与不带条件的innerjoin相同。带sing条件的left join与 natrual left join相同。

    4、语法:

    inner join,cross join [条件]。没有条件就是笛卡尔积。
      left join, right join 条件。左和右的区别在于,如果是左连接,那么即使左表的记录,连接不到,也会在最终结果内显示。
      natrual [left|right] join,内可以省略条件,外必须使用条件。自然连接会重新规划列名,因此条件就不能是表名.字段名的形式。可以理解i成自然连接后,就成了一个表了。而 外和内是有连接条件的两个表。

    5、条件:

    Where和on可以使用条件表达式;using (公共字段),需要使用公共字段。
      内联可以使用where on 和using条件;外联只可以使用using和on作为条件,外连接不能使用where。
      通常 where还有筛选的含义,而on和using只有连接条件的意思。因此通常连接条件使用on或using。而筛选条件使用where加以区分。建议是,在有同名字段的时候使用using,而在通用条件时,使用on。在数据过滤时(不是指连接过滤)使用where。

    6、测试用例1:

      drop table if exists one;
      create table one (
      one_id int,
      one_data char(1),
      public_field int
      );
    
      insert into one values
      (1, 'a', 10),
      (2, 'b', 20),
      (3, 'c', 30);
    
      drop table if exists two;
      create table two (
      two_id int,
      two_data char(1) not null default 't',
      public_field int
      );
    
      insert into two values
      (2, 'B', 20),
      (3, 'C', 30),
      (4, 'D', 40);
    

    7、测试程序2:

    join

       #教师信息
       create table join_teacher(
       id int primary key auto_increment,
       t_name varchar(10),
       gender enum('male', 'female', 'secret')
       )engine innodb character set utf8;
    
      insert into join_teacher values
      (1, '韩信','male'), 
      (2, '貂蝉', 'female'),
      (3, '刘备', 'secret'),
      (4, '孙权', 'male');
    
       #班级信息
      create table join_class(
      id int primary key auto_increment,
      c_name char(7),
      room char(3)
      )engine innodb character set utf8;
    
      insert into join_class values
      (1, 'php0115', '120'),
      (2, 'php0224', '214'),
      (3, 'php0232', '112'),
      (4, 'php1111', '111');
    
      #代课时间表
      create table join_teacher_class(
      id int primary key auto_increment,
      t_id int,
      c_id int,
      days tinyint,
      begin_date date,
      end_date date
      )engine innodb character set utf8;
    
      insert into join_teacher_class values
      (1, 1, 1, 15, '2013-01-12', '2016-01-12'),
      (2, 1, 2, 16, '2012-01-12', '2013-01-12'),
      (3, 1, 3, 19, '2013-05-12', '2016-01-12'),
      (4, 2, 3, 20, '2013-03-01', '2015-01-12'),
      (5, 3, 1, 19, '2014-05-12', '2015-01-12'),
      (6, 1, 3, 21, '2012-02-11', '2017-01-12'),
      (7, 3, 2, 16, '2012-05-07', '2013-01-12'),
      (8, 1, 1, 19, '2015-01-12', '2016-01-12');
    

    tbl1_left inner join tbl1_right on connect_condition

    有条件内连接

    select join_teacher.t_name, join_teacher_class.begin_date, join_teacher_class.days
    from join_teacher inner join
     join_teacher_class on join_teacher.id = join_teacher_class.t_id;
    

    外连接

    select join_teacher.t_name, join_teacher_class.begin_date, join_teacher_class.days
    from join_teacher left outer join 
    join_teacher_class on
    join_teacher.id = join_teacher_class.t_id;
    

    默认内连接并且无条件

    select join_teacher.t_name, join_teacher_class.begin_date, join_teacher_class.days
    from join_teacher join
     join_teacher_class;
    

    where语句

    select join_teacher.t_name, join_teacher_class.begin_date, join_teacher_class.days
    from join_teacher inner join
     join_teacher_class where
     join_teacher.id = join_teacher_class.t_id;
    
    select join_teacher.t_name, join_teacher_class.begin_date, join_teacher_class.days
    from join_teacher inner join
     join_teacher_class on
     join_teacher.id = join_teacher_class.t_id and
     days > 20;
    
    select join_teacher.t_name, join_teacher_class.begin_date, join_teacher_class.days
    from join_teacher inner join
     join_teacher_class where
     join_teacher.id = join_teacher_class.t_id where 
    days > 20;
    

    最好的一种

    select join_teacher.t_name, join_teacher_class.begin_date, join_teacher_class.days
    from join_teacher inner join
     join_teacher_class on
     join_teacher.id = join_teacher_class.t_id where 
    days > 20;
    

    别名的使用

    select join_teacher.t_name, join_teacher.id as
     t_id, join_teacher_class.id as
     tc_id,join_teacher_class.begin_date, join_teacher_class.days from join_teacher inner join
     join_teacher_class on
     join_teacher.id = join_teacher_class.t_id ;
    
    1.png

    8、外连接

    join左边的表就是左表,右边的表就是右表。
    分类
      左边连接/右边连接/全外连接
    左连接:left [outer] join
      在左连接时,如果出现左边表,数据连接不到右边表的情况,则坐标表的数据在最终结果内被保留,而如果出现右边表的数据连接不到左边表的情况时,右表的数据就会被丢弃。

    select join_teacher.t_name, join_teacher.id as 
    t_id, join_teacher_class.id as tc_id,
    join_teacher_class.begin_date, 
    join_teacher_class.days from 
    join_teacher left join join_teacher_class on 
    join_teacher.id = join_teacher_class.t_id ;
    
    1.png

    9、自然连接

    通过mysql自己的判断完成连接过程;不需要指定连接条件,mysql会使用多表内的,相同的字段,作为连接条件。
    natural

    select * from one  natural join two;
    select * from one inner join two using (public_field);
    
    select * from one natural left join two;
    select * from one left join two using (public_field);
    
    select * from one natural right join two;
    select * from one right join two using (public_field);
    

    10、多表连接

    多表连接

    create table info_class(
    id int,
    class_name varchar(20)
    );
    
    create table info_student(
    id int,
    student_name varchar(20),
    class_id int
    );
    
    create table info_student_info(
    id int,
    student_detail varchar(50)
    );
    
    select * from info_class as c left join
    info_student as s on
    c.id = s.class_id left join
    info_student_info as si on
    s.id = si.id where c.class_name = 'php0331';
    
    1.png

    相关文章

      网友评论

        本文标题:连接查询

        本文链接:https://www.haomeiwen.com/subject/anoaittx.html