网站首页 > 技术文章 正文
建表与数据准备
create database day4;
use day4;
# 建表
create table department(
id int unsigned not null unique,
name char(20)
);
create table employee(
id int unsigned primary key auto_increment,
name char(12) not null,
gender enum('male','female') not null default 'male',
age int unsigned,
dep_id int unsigned not null
);
# 写入数据
insert into department values
(100,'技术'),
(101,'人事'),
(102,'销售'),
(103,'运营');
# 免责声明:以下名字均是faker name生成的,请勿对号入座。
insert into employee(name,gender,age,dep_id) values
('唐建华','male',18,100),
('黄淑珍','female',48,101),
('李畅','male',38,101),
('华桂珍','female',28,102),
('钟涛','male',18,100),
('廖婷婷','female',18,104);
连表
不加条件的连表就是笛卡尔积,案例如下:
select *
from employee,department;
这样生成了24条记录,即左表6条×右表4条。这种连表方式极少用到,因为这样生成太多冗余数据。
常用的连表方式是根据某个共同字段将两个表进行连表,一共有以下四种类型:
一、内连表
语法案例:
select *
from department
inner join employee
on department.id=employee.dep_id;
运行结果:
注意事项:
内连表会舍弃左表和右表两边不匹配的数据!
请认真看department表,这里有4个部门;employee表,这里有6个员工。
连表以后只有5条记录,其中department表中“运营”记录被舍弃,employee表中’廖婷婷’记录被舍弃。
二、左外表
语法案例:
select *
from department
left join employee
on department.id=employee.dep_id;
运行结果:
注意事项:
左外表会保留左表全部数据,舍弃右表不匹配的数据!
请认真看department表,这里有4个部门;employee表,这里有6个员工。
连表以后只有6条记录,其中department表中的4条记录齐全,employee表中’廖婷婷’记录被舍弃。
三、右外连表
语法案例:
select *
from department
right join employee
on department.id=employee.dep_id;
运行结果:
注意事项:
右外表会保留右表全部数据,舍弃左表不匹配的数据!
请认真看department表,这里有4个部门;employee表,这里有6个员工。
连表以后只有6条记录,其中department表中“运营”记录被舍弃,employee表中6条记录齐全。
四、全外连表
语法案例:
mysql不支持全外连表,但是可以使用union变通实现全外连表,代码如下:
select *
from department
left join employee
on department.id=employee.dep_id
union
select *
from department
right join employee
on department.id=employee.dep_id;
运行结果:
注意事项:
全外连表不会舍弃任何数据!
请认真看department表,这里有4个部门;employee表,这里有6个员工。
连表练习
- 查询所有人事部的员工名单:
select e.name 姓名
from department d # 部门表重命名为d
inner join employee e #员工表重命名为e
on d.id=e.dep_id # 部门表的id字段与员工表的dep_id字段建立内连接
where d.name='人事'; # 筛选部门名字是'人事'的记录
- 查询人事部年龄大于40岁的员工名单:
select e.name 姓名
from department d
inner join employee e
on d.id=e.dep_id
where d.name="人事" and e.age>40; # 筛选部门名字是人事且员工年龄大于40岁的记录
- 查询年龄大于20岁的员工及所在部门:
select e.name 姓名,d.name 部门
from department d
inner join employee e
on d.id=e.dep_id
where age>20;
- 查询所有部门的名字和员工人数:
select d.name 部门,count(e.id) 人数
from department d
left join employee e
on d.id=e.dep_id
group by d.name; # 按部门名字进行分组
注意:这里要用左外连表,因为所有的部门数据都要保留,不能遗漏没人的部门。
5. 查询所有部门的名字和员工人数,按人数从高到低排列:
select d.name 部门,count(e.id) 人数
from department d
left join employee e
on d.id=e.dep_id
group by d.name
order by 人数 desc; # 按人数从高到低排序
子查询
子查询是指查询中嵌套查询。
具体看下列案例:
- 查询平均年龄在25岁以上的部门:
select d.name 部门
from department d
where id in( # 筛选部门id在平均年龄25岁以上的
select dep_id
from employee
group by dep_id # 按部门id分组
having avg(age)>25 # 按平均年龄过滤部门,只保留平均年龄大于25的
);
- 查询不足1人的部门名(子查询得到的是有人的部门id)
select name
from department d
where d.id not in(
select dep_id from employee
group by dep_id
having count(id)>=1
); # 这种写法适用性更广,若将1改成2可找出人数仅1人或不足1人的部门
- 查询大于单位平均年龄的员工
select name,age
from employee
where age>( # 括号内子句中计算单位的平均年龄
select avg(age)
from employee
);
多表查询总结:
- 遇到既可使用子查询实现也可使用连表查询实现的情况,优先考虑使用连表查询,因为连表查询效率比子查询高。
- 写多表查询代码时要分层分步实现,每一步经过验证无误后,再将若干步骤拼接起来。
- 注重书写格式,建议参考上述案例中select父句和子句缩进书写格式,既可以方便书写注释又方便识别父句与子句,大大提高代码可读性。
- 注意select语句的子句执行顺序,请参照子句执行的顺序书写子句。
猜你喜欢
- 2024-10-27 MySQL左查询最全介绍(sql 左查询)
- 2024-10-27 mysql查询指定父级下所有子级(mysql根据子节点查父)
- 2024-10-27 mysql进行数据查询(单表查询)(mysql 查询数据表)
- 2024-10-27 【执行计划】MySQL如何执行查询?(mysql执行查询语句)
- 2024-10-27 MySQL查询列必须和group by字段一致吗?
- 2024-10-27 查看MySQL所有数据库列表(mysql怎么查看数据库列表)
- 2024-10-27 「mysql」mysql调优时必须掌握的慢查询语句排查命令
- 2024-10-27 有一张1000W 数据记录的表,主键id自增,如何随机抽取10条记录?
- 2024-10-27 MySQL进阶实战7,查询的执行过程(mysql查询机制)
- 2024-10-27 说说 MySQL 子查询(在mysql中子查询是)
- 11-26Win7\8\10下一条cmd命令可查得笔记本电脑连接过的Wifi密码
- 11-26一文搞懂MySQL行锁、表锁、间隙锁详解
- 11-26电脑的wifi密码忘记了?一招教你如何找回密码,简单明了,快收藏
- 11-26代码解决忘记密码问题 教你用CMD命令查看所有连接过的WIFI密码
- 11-26CMD命令提示符能干嘛?这些功能你都知道吗?
- 11-26性能测试之慢sql分析
- 11-26论渗透信息收集的重要性
- 11-26如何查看电脑连接过的所有WiFi密码
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)