声明: 本文所有名字都不代指具体明星!只是为了方便理解借用名字而已!!请勿上升真人!!!❤
左连接、右连接、内连接的区别?
例子:
男生表:
姓名 | 屌丝 | 李四 | 王五 | 高富帅 | 郑七 |
---|---|---|---|---|---|
配偶 | A | B | C | D | E |
女生表:
姓名 | 空姐 | 大S | 张柏芝 | 阿娇 | 林黛玉 | 宝钗 |
---|---|---|---|---|---|---|
配偶 | B | C | D | D | E | F |
这时,主持人大声说:
所有的男士站到舞台上,带上自己的配偶,(没有的拿块牌子,上写NULL)
思考:张三(屌丝)上不上舞台呢?
答:上
问:张三(屌丝)没有对应的行怎么办?
答:用NULL补齐。
结果如下:
姓名 | 屌丝 | 李四 | 王五 | 高富帅 | 高富帅 | 郑七 |
---|---|---|---|---|---|---|
配偶 | A | B | C | D | D | E |
女生姓名 | NULL | 空姐 | 大S | 阿娇 | 张柏芝 | 林黛玉 |
配偶 | NULL | B | C | D | D | E |
多行的高富帅对应的行,不能合并成一行,因为这样就违反了数据库的规则。
create table boy(
bname varchar(20),
other char(1)
)engine myisam charset utf8;
create table girl(
gname varchar (20),
other char(1)
)engine myisam charset utf8;
insert into boy
values
('屌丝','A'),
('李四','B'),
('王五','C'),
('高富帅','D'),
('郑七','E');
insert into girl
values
('空姐','B'),
('大S','C'),
('阿娇','D'),
('张柏芝','D'),
('林黛玉','E'),
('宝钗','F');
# 开始做左连接:
select boy.*,girl.* from
boy left join girl on boy.other = girl.other;
这种情况就是 男生 left join 女生
主持人说:所有女生请上舞台,有配有的带着,没有的写NULL
# 这次以女生为准,女生 left join 男生
select boy.*,girl.* from
girl left join boy on girl.other = boy.other;
注意: a left join b 并不是说 a 表的就一定在左边,而是说在查询数据时,以 a 表为准
NULL:不是选出来的,而是补出来的!
左右连接是可以互换的:
A left join B == B right join A
# 这个题用右连接做:
select boy.*,girl.* from
boy right join girl on girl.other = boy.other;
注意:既然左右连接可以互换,尽量用左连接,出于移植时兼容性方面的考虑。
内连接的特点:
主持人说:所有有配偶的男生/女生,走到舞台上来。
# 这次屌丝和宝钗都不能上去
select boy.*,girl.* from
boy inner join girl on boy.other = girl.other;
如果从集合的角度:
A inner join B 和 left\right join 的关系:
内连接时左右连接的交集。
问题:主持人说,所有男生/女生走上舞台,又配偶的带上配偶,没有的拿NULL的牌子:
这时是左右连接的并集。这种叫外连接,但是在MySQL中不支持外连接。
两道题:
1.预习union,合并结果集,完成外连接的效果。
2. 根据给出的表结构按要求写出SQL语句:
match赛程表:
字段名称 | 字段类型 | 描述 |
---|---|---|
matchID | int | 主键 |
hostTeamID | int | 主队的ID |
guestTeamID | int | 客队的ID |
matchResult | varchar(20) | 比赛结果,如(2:0) |
matchTime | date | 比赛开始时间 |
Team参赛队伍表
字段名称 | 字段类型 | 描述 |
---|---|---|
teamID | int | 主键 |
teamName | varchar(20) | 队伍名称 |
match的hostTeamID与guestTeamID都与Team中的teamID关联。
查出2006-6-1到2006-7-1之间举行的所有比赛,并且用以下形式列出:
拜仁 2:0 不米梅 2006-6-21
create table m( # match是MySQL的一个关键字,不能用于做表名
mid int,
hid int,
gid int,
mres varchar(10),
matime date
)engine myisam charset utf8;
create table t (
tid int,
tname varchar(20)
)engine myisam charset utf8;
insert into m
values
(1,1,2,'2:0','2006-05-21'),
(2,2,3,'1:2','2006-06-21'),
(3,3,1,'2:5','2006-06-25'),
(4,2,1,'3:2','2006-07-21');
insert into t
values
(1,'国安'),
(2,'申花'),
(3,'布尔联队');
select t1.tname as guestname,mres,t2.tname as hostname,matime from
(m left join t as t1 on m.gid=t1.tid)
left join t as t2 on m.hid=t2.tid
where month(m.matime)= 6;
要求取出比赛的结果,并且队伍id应显示出队名。
简单一点:取出主客队的id,并不做特殊处理。
select hid,mres,gid,matime from m;
再前进一小步,根据hid,左联t表,查出主队的队伍名称。即简单的2张表左连接:
select hid,tname,mres,gid,matime from
m left join t on m.hid = t.tid;
这一步取出了主队的名称。再将这个结果集当成一张新表,同理取出客队的名称。
select hid,t1.tname,mres,gid,t2.tname,matime from
(m left join t as t1 on m.hid = t1.tid)
left join t as t2 on m.gid=t2.tid;
改进后得到最终答案:
select t1.tname as hostname,mres,t2.tname as guestname,matime from
(m left join t as t1 on m.hid = t1.tid)
left join t as t2 on m.gid=t2.tid
where month(m.matime)=6;