mysql的连接查询,相必在网上都能找到很多的教程,博主今天不做老话常谈,不走重复路线
1.建表
–1.学生表
Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别
–2.课程表
Course(c_id,c_name,t_id) – –课程编号, 课程名称, 教师编号
–3.教师表
Teacher(t_id,t_name) –教师编号,教师姓名
–4.成绩表
Score(s_id,c_id,s_score) –学生编号,课程编号,分数
2.准备测试数据
--建表
--学生表
CREATE TABLE `Student`(
`s_id` VARCHAR(20),
`s_name` VARCHAR(20) NOT NULL DEFAULT '',
`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
PRIMARY KEY(`s_id`)
);
--课程表
CREATE TABLE `Course`(
`c_id` VARCHAR(20),
`c_name` VARCHAR(20) NOT NULL DEFAULT '',
`t_id` VARCHAR(20) NOT NULL,
PRIMARY KEY(`c_id`)
);
--教师表
CREATE TABLE `Teacher`(
`t_id` VARCHAR(20),
`t_name` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(`t_id`)
);
--成绩表
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_id`)
);
--插入学生表测试数据
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
--课程表测试数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');
--教师表测试数据
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
--成绩表测试数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);
3.注意事项
-- 准备条件,去掉 sql_mode 的 ONLY_FULL_GROUP_BY 否则此种情况下会报错:
-- Expression #1 of select list is not in group by clause and contains nonaggregated column 'userinfo.
-- 原因:
-- MySQL 5.7.5和up实现了对功能依赖的检测。如果启用了only_full_group_by SQL模式(在默认情况下是这样),
-- 那么MySQL就会拒绝选择列表、条件或顺序列表引用的查询,这些查询将引用组中未命名的非聚合列,而不是在功能上依赖于它们。
-- (在5.7.5之前,MySQL没有检测到功能依赖项,only_full_group_by在默认情况下是不启用的。关于前5.7.5行为的描述,请参阅MySQL 5.6参考手册。)
-- 执行以下个命令,可以查看 sql_mode 的内容。
SHOW SESSION VARIABLES;
SHOW GLOBAL VARIABLES;
select @@sql_mode;
-- 更改
set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
- 闲话少说,打开一下话匣子吧
连接查询有很多,今天博主侧重点分析左外联查。小伙伴们把左外联查彻底搞明白了,其它查询也是同样的道理
先看一组例子
(1)左表是student,右表是score,连接条件仅限于等号
select st.,sc. from student st left join score sc
on sc.s_id=st.s_id
执行结果:
(2)左表是student,右表是score,连接条件包括and
select st.,sc. from student st left join score sc
on sc.s_id=st.s_id and sc.s_id is not null
(3) 左表是score,右表是student,连接条件包括and
select st.,sc. from score sc left join student st
on sc.s_id=st.s_id and sc.s_id is not null
执行结果:
(3)左表是student,右表是score,连接条件仅限于等号,但是存在where筛选条件
select st.,sc. from student st left join score sc
on sc.s_id=st.s_id where sc.s_id is not NULL
(4)左表是student,右表是score
select st.,sc. from student st
left join score sc on sc.s_id=st.s_id and st.s_name in (‘赵雷’,‘钱电’)
(5)左表是student,右表是score
select st.,sc. from student st
left join score sc on sc.s_id=st.s_id
where st.s_name in (‘赵雷’,‘钱电’)
(6)左表是student,右表是score
select st.,sc. from student st
left join score sc on sc.s_id=st.s_id and sc.s_id in(‘01’,‘02’)
(7)左表是student,右表是score
select st.,sc. from student st
left join score sc on sc.s_id=st.s_id and sc.s_id in(‘01’)
(8)左表是student,右表是score
select st.,sc. from student st
left join score sc on sc.s_id=st.s_id and st.s_name =‘钱电’ and sc.s_id in(‘01’)
(9)左表是student,右表是score
select st.,sc. from student st
left join score sc on sc.s_id=st.s_id and sc.s_id in(‘01’,‘02’,‘03’,‘04’,‘05’,‘06’,‘07’,‘08’)
小结:
(1)左外联查,以左表作为主表,右表数据根据连接条件往左表拼凑数据,最终形成一张完整的临时表
(2)连接条件分为连接前筛选与连接后筛选,其中on后面的条件做的都是连接前的筛选,where后面的连接条件做的都是连接后的筛选
(3)拓展一下,on后面的筛选条件可以和where后面的筛选条件,比如and, or, >,>=,=,<=,<,in等等
(4)on后面的筛选条件以左表的筛选条件为主,
1- 当左表连接条件与右表连接条件同时存在时,以左表连接条件为主,右表筛选条件为辅。同时左表筛选条件决定着最终形成的临时表的数据条数。
2- 当只有左表筛选条件时,左表筛选条件决定着最终形成的临时表的数据条数。
3- 当只有右表筛选条件时,右表筛选条件决定着最终形成的临时表的数据条数。
右表筛选条件相对于左表做筛选