MySQL数据库中的多表查询

创建两个表,并添加如下数据(此表对以下讨论均适用)

#user_info表
create table user_info(
      id int(2) primary key,
      user_name varchar(12) unique,
      password varchar(15) not null,
      real_name varchar(8) not null,
      age int(3)
); 

#address表
create table address(
      id int(2) primary key,
      user_id int(2) not null,	#user_id是uesr_info表中的id,是理论上的外键,将两个表联系起来,可以插入垃圾数据
      real_name varchar(8),
      mobile char(11),
      address varchar(150)
); 

insert into user_info values(1,'浅唱灬幸福','8912@321','王晓明',12);
insert into address values(1,1,'王小明','15516472282','山西太原');
insert into address values(2,1,'王鑫','18404905139','山西大同');
insert into address values(3,1,'任建','15333021730','山西晋城');
 
insert into user_info values(2,'ぅ浮生若梦〤','56701wz','王楠',36);
insert into address values(4,2,'王楠','15010303314','北京海淀');
insert into address values(5,2,'赵婕','18435224278','山西长治');
 
insert into user_info values(3,'街角の风铃','27w4921','李晓飞',9);

insert into address values(6,6,'刘倩','13159775555','吉林长春');	#垃圾数据,但可以添加成功

在讨论多表查询之前,首先讨论子查询,以此引出多表查询。

子查询

什么是子查询:

查询中的查询即为子查询,一般使用括号将子查询sql括起来,如下SQL语句: select * from (select * from user_info) users

什么时候用子查询:

当在查询过程中需要知道一个已知量的不确定数据时使用子查询

例如:查询出来姓名为王晓明的所有地址

思路:需要先根据王晓明(已知量)查出user_info表中的id,再根据id=user_id,在地址表中查出所有的地址信息(不确定数据)
1,一般情况,我们会用两条SQL语句查询,如下

select id from user_info where real_name='王晓明'	#首先得到的是王晓明的id
select * from address where user_id=1		#再根据id在地址表中查询

在这里插入图片描述
在这里插入图片描述
2,事实上,我们学习了子查询后可以用子查询的方法,如下SQL语句

   select * from address where user_id=(select id from user_info where real_name='王晓明');		#使用子查询先通过姓名获取id,然后再通过用户id查询地址表

在这里插入图片描述
注意“=”:如果子查询只返回一个结果,则可以使用=,也可以使用in;但是如果确定子查询永远只返回一个结果,则不建议使用in,例如上面SQL语句可变为如下SQL语句
select * from address where user_id in(select id from user_info where real_name=‘王晓明’);

3,上述子查询前一个SQL语句只返回了一个结果,如果子查询返回多个结果,则使用in
查询所有姓王的地址信息,先使用一般方法

select id from user_info where real_name like '王%'	#执行此语句会返回多个值。
select * from address where user_id in(1,2)	#上述语句返回了多个值,所以用in

在这里插入图片描述
在这里插入图片描述
使用子查询的方法

select * from address where user_id in(select id from user_info where real_name like '王%')	

在这里插入图片描述
上述输出结果知识address中的信息,并不能直观的看见user_info中的信息,使用多表查询可以显示出两个表中的数据,接下来讨论多表查询。

多表查询

多个表关联查询需要依据多表之间列关系将其连接起来,这种连接方式分为三种:内连接(inner join)、外连接(outer join)及交叉连接(cross join)

外连接(outer join)

如果依据多表之间列关系进行外连接,查询结果集不仅仅包括满足on连接条件的数据行,还包括不满足on连接条件的数据行。

left join(左连接)

左外连接(left [outer] join):返回的结果集中不仅包含表之间满足on连接条件的全部数据行,还包含左表(“left [outer] join”关键字左边的表)不满足on连接条件的数据行;
执行如下SQL语句

select ui.*,addr.*
from user_info as ui
left join address as addr
on addr.user_id=ui.id

在这里插入图片描述

上述输出结果中字段名为id且id为3的数据存在于左边表中,但是在右边表中没有对应的地址,并不满足on中的条件,依旧显示。

right join(右连接)

右外连接(right [outer] join):返回的结果集中不仅包含表之间满足on连接条件的全部数据行,还包含右表(即“right [outer] join”关键字右边的表)不满足on连接条件的数据行;

select ui.*,addr.*
from user_info as ui
right join address as addr
on addr.user_id=ui.id

在这里插入图片描述

上述输出结果中,字段名为id(1)且id(1)为3的数据存在于右边表中,在左边表中没有对应的用户名,也会输出。

总结左右连接:以left或right为参照,如果是left,则显示该关键字左边表中所有数据,如果从表没有对应的数据,则显示null;同样,如果是right,则显示该关键字右边表中所有数据,如果从表没有对应的数据,则显示null

full join(全连接)

全外连接(full [outer] join):返回的结果集中不仅包含表之间满足on连接条件的全部数据行,还包含左表(“full [outer] join”关键字左边的表)和右表(“full [outer join”关键字右边的表)中不满足on连接条件的数据行;

select ui.*,addr.*
from user_info as ui
full join address as addr
on addr.user_id=ui.id		#语句正确

MySQL数据库不支持全连接,以下结果为orcal数据库中输出的
在这里插入图片描述

内连接(inner join)

如果依据多个表之间列关系进行内连接,查询结果集仅包括满足连接条件的数据行。内连接分为等值连接、不等值连接以及自然连接,其中等值连接最为常见。
下边介绍等值连接:查询出的结果为两个表共有的,是交集。

select ui.*,addr.*
from user_info as ui
inner join address as addr
on addr.user_id=ui.id

在这里插入图片描述

交叉连接(across join)

左表(“cross join”关键字左边的表)中的每一行与右表(“cross join”关键字右边的表)中的所有行组合,交叉联接的结果是一个笛卡尔积。

select ui.*,addr.* 
from user_info ui 
cross join address addr order by real_name;	#为了直观传达信息,将连接后的数据根据real_name排序。输出结果更加直观的得到是两个表中数据(认为一行为一条数据)的笛卡尔积,共18条数据。

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值