连接查询

连接查询_第1张图片
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 ;
连接查询_第2张图片
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 ;
连接查询_第3张图片
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';
连接查询_第4张图片
1.png

你可能感兴趣的:(连接查询)