SQL基础总结-03
join 连接
select … from … where … group by … having … order by … limit …;
过滤(条件) 分组 过滤(条件) 排序 限定个数
-- 上述语句执行顺序,先 from -> where -> group by -> select -> having -> order by -> limit
如果有两张相关的表stu和class:
stu join class 结果就生成了一张表,什么名字不知道
stu表:
id | name | classid |
---|---|---|
1 | A | 1 |
2 | B | 1 |
3 | C | 2 |
4 | D | 2 |
5 | E | 1 |
class表:
id | name | manager |
---|---|---|
1 | 超越 | 黄飞鸿 |
2 | 大木 | 方世玉 |
-- 以上两张表执行下面的语句
stu join class; -- 是一张表
结果:
id | name | classid | id | name | manager |
---|---|---|---|---|---|
1 | A | 1 | 1 | 超越 | 黄飞鸿 |
1 | A | 1 | 2 | 大木 | 方世玉 |
2 | B | 1 | 1 | 超越 | 黄飞鸿 |
2 | B | 1 | 2 | 大木 | 方世玉 |
3 | C | 2 | 1 | 超越 | 黄飞鸿 |
3 | C | 2 | 2 | 大木 | 方世玉 |
4 | D | 2 | 1 | 超越 | 黄飞鸿 |
4 | D | 2 | 2 | 大木 | 方世玉 |
5 | E | 1 | 1 | 超越 | 黄飞鸿 |
5 | E | 1 | 2 | 大木 | 方世玉 |
1、如果要访问其中一个id字段,前面加上对应的表名:stu.id
select * from stu join class where classid=2 and stu.id%2=1 group by stu.name;
2、用下面的stu表、class表
stu表:
id | name | classid |
---|---|---|
1 | A | 1 |
2 | B | 1 |
3 | C | 2 |
class表:
id | name | manager |
---|---|---|
1 | 超越 | 黄飞鸿 |
2 | 大木 | 方世玉 |
stu join class;
结果:一个名为 stu join class的新表
id | name | classid | id | name | manager |
---|---|---|---|---|---|
1 | A | 1 | 1 | 超越 | 黄飞鸿 |
1 | A | 1 | 2 | 大木 | 方世玉 |
2 | B | 1 | 1 | 超越 | 黄飞鸿 |
2 | B | 1 | 2 | 大木 | 方世玉 |
3 | C | 2 | 1 | 超越 | 黄飞鸿 |
3 | C | 2 | 2 | 大木 | 方世玉 |
id对于语句 stu join class,可以用on条件再来修改优化:stu join class on 条件可以过滤某些已经无用的字段,不符合条件的删除
stu join class on class.id=classid; -- 当id字段冲突,前面加上原来的表名称,classid就一个,不会冲突
结果如下:
id | name | classid | id | name | manager |
---|---|---|---|---|---|
1 | A | 1 | 1 | 超越 | 黄飞鸿 |
2 | B | 1 | 1 | 超越 | 黄飞鸿 |
3 | C | 2 | 2 | 大木 | 方世玉 |
如果在上述表的基础上,select *仍然显示全部;
select stu.id, classid, class.id from stu join class on class.id=classid;
结果:
id | classid | id |
---|---|---|
1 | 1 | 1 |
2 | 1 | 1 |
3 | 2 | 2 |
3、看一个left join的用法
stu left join class on classid=class.id;
join和left join区别:
- left join 必须有on条件
- left join会检查左( 因为用的是left join )边的表stu的数据是否都包含在新生成的表中,如果雨是全部包含,则跟join没区别,若未完全包含,则用null与不包含的行组成新行加入新生成的表
- left join左右两边的表交换,结果会不一样
stu表:
id | name | classid |
---|---|---|
1 | A | 1 |
2 | B | 1 |
3 | C | 2 |
class表:
id | name | manager |
---|---|---|
1 | O | 黄飞鸿 |
stu left join class on classid=class.id; -- 如果用的是join只会显示前两行,left join就会把左边stu表未包含的第三行给包含进去,对应右边的表的填入NULL
结果:
id | name | classid | id | name | manager |
---|---|---|---|---|---|
1 | A | 1 | 1 | O | 黄飞鸿 |
2 | B | 1 | 1 | O | 黄飞鸿 |
3 | C | 2 | NULL | NULL | NULL |
如果下面这条语句会返回什么样的表:
class left join stu on classid=class.id;
结果:
id | name | manager | id | name | classid |
---|---|---|---|---|---|
1 | O | 黄飞鸿 | 1 | A | 1 |
1 | O | 黄飞鸿 | 2 | B | 1 |
那么对于right join:跟left join差不多,反一下而已;A right join B = B left join A;
4、当有多张表,如三张表A、B、C的时候:A join B on … join C …; 实际顺序是 先执行A join B,A join B 的结果再去join C,A join B join C的结果再去join D;
问题:查询id是1的学生的班级主任名称
分析:要查询两张相关的表的数据,要用join
黑客信仰——世界上没有一个绝对安全的系统,只要这个系统是人设计的,就会有漏洞,因为人性具有弱点。