1 创建建数据库、创建建数据表、查看数据库、查看数据表
-- 01.查看mysql服务器中所有数据库
show databases;
-- 02.进入某一数据库(进入数据库后,才能操作库中的表和表记录)
use test; /*进入test库*/
-- 查看已进入的库
select database();
-- 03.查看当前数据库中的所有表
show tables;
-- 04.删除mydb1库
-- 语法:drop database 库名;
/* 思考:当删除的表不存在时,如何避免错误产生? */
drop database if exists mydb1;
-- 05.重新创建mydb1库,指定编码为utf8
-- 语法:create database 库名 charset 编码;
create database mydb1 charset utf8;
-- 如果创建库,不指定编码,默认使用服务器默认的编码(有可能是latin1/iso9959-1,其中没有中文字符)
-- 如果不存在则创建mydb1;
create database if not exists mydb1 charset utf8;
-- 06.查看建库时的语句(并验证数据库库使用的编码)
-- 语法:show create database 库名;
show create database mydb1;
-- 07.进入mydb1库,删除stu学生表(如果存在)
-- 语法:drop table 表名;
drop table if exists stu;
-- 08.创建stu学生表(编号[数值类型]、姓名、性别、出生年月、考试成绩[浮点型])
/* 建表的语法:
create table 表名(
列名 数据类型,
列名 数据类型,
...
); */
create table stu(
id int primary key auto_increment,/*设置主键约束,自增*/
name varchar(50),
gender varchar(2),
birthday date,
score double
);
-- 09.查看stu学生表结构
desc stu;
2 新增、修改、删除表记录
-- 10.往学生表(stu)中插入记录(数据)
-- 插入记录:insert into 表名(列1,列2,列3...) values(值1,值2,值3...);
insert into stu(id,name,gender,birthday,score) value(1,'王海涛','男','1999-6-2','70');
insert into stu values(1,'流川枫1','男','1953-6-2','60');
insert into stu values(2,'流川枫2','男','1956-6-7','80');
insert into stu values(3,'流川枫3','男','1950-6-9','99');
insert into stu values(7,'流川枫7','男','1958-6-9','99');
/*id 设置了主键且设置了自增,插入数据时id设置为null。如果设置了主键自增,还是可以设置主键的值*/
insert into stu values(null,'李四','男','1955-6-2','50');
insert into stu values(null,'流川枫','女','1955-6-2','70');
/*mysql 数据库的字段约束
如果id是编号,编号应该是唯一的且不能为空,那么如何设置?在创建表时
主键约束:id int primary key
唯一约束:如果为一个列添加唯一约束,这一列的值不能为空,但是可以重复
username varchar(50) unique
非空约束:
gender varchar(2) not null
*/
/* 提示:
设置编码:set names gbk; 这条命令是通知mysql服务器,在接收cmd发送的数据时,
使用GBK编码来接收。这样依赖,发送的编码是GBK,接收数据的编码也是GBK,数据不会
出现乱码(不管是通过cmd或者第三方工具或者java程序),只对当前窗口有效,如果新开一个cmd窗口,必须重新设置编码
查看MySQL数据库使用的编码:show variables like 'char%';
mysql --default-character-set=gbk -uroot -proot */
-- 11.查询stu表所有学生的信息
select * from stu;
-- 12.修改stu表中所有学生的成绩,加10分特长分
-- 修改语法: update 表名 set 列=值,列=值,列=值...;
update stu set score = score+10;
-- 13.修改stu表中王海涛的成绩,将成绩改为88分。
update stu set score = 88 where name='流川枫7';
/* 提示:where子句用于对记录进行筛选过滤,
保留符合条件的记录,将不符合条件的记录剔除。*/
-- 14.删除stu表中所有的记录
-- 删除记录语法: delete from 表名 [where条件]
delete from stu where gender='女';
-- 仅删除符合条件的
-- 删除所有记录,再插入数据,则id从之前的记录开始,如之前的id最大值是12,则新增的id从13开始
delete from stu;
-- 摧毁重建表,插入数据id从1开始
truncate table stu;
3 基础查询、where子句查询,模糊查询
3.1 新建数据库db10并插入数据
-- --------------------------------------------------
-- 创建db10库、emp表并插入记录
-- --------------------------------------------------
-- 删除db10库(如果存在)
drop database if exists db10;
-- 重新创建db10库
create database db10 charset utf8;
-- 选择db10库
use db10;
-- 删除员工表(如果存在)
drop table if exists emp;
-- 创建员工表
create table emp(
id int primary key auto_increment, -- 员工编号
name varchar(50), -- 员工姓名
gender char(1), -- 员工性别
birthday date, -- 员工生日
dept varchar(50), -- 所属部门
job varchar(50), -- 所任职位
sal double, -- 薪资
bonus double -- 奖金
);
-- 往员工表中插入记录
insert into emp values(null,'王海涛','男','1995-03-25','培优部','金牌讲师','1800','300');
insert into emp values(null,'齐雷','男','1994-04-6','培优部','金牌讲师','2500','600');
insert into emp values(null,'刘沛霞','女','1996-06-14','培优部','金牌讲师','1400','300');
insert into emp values(null,'陈子枢','男','1991-05-18','培优部','部门总监','4200','500');
insert into emp values(null,'刘昱江','男','1993-02-18','培优部','金牌讲师','1600','500');
insert into emp values(null,'王克晶','女','1998-07-18','就业部','金牌讲师','3700','600');
insert into emp values(null,'苍老师','男','1995-08-18','就业部','部门总监','4850','400');
insert into emp values(null,'范传奇','男','1999-03-18','就业部','金牌讲师','3200','600');
insert into emp values(null,'刘涛','男','1990-04-18','就业部','金牌讲师','2700','400');
insert into emp values(null,'韩少云','男','1980-05-18',null,'CEO','50000',null);
3.2 基础查询
-- 15.查询emp表中的所有员工,显示姓名,薪资,奖金
select name,sal,bonus from emp;
-- 16.查询emp表中的所有员工,显示所有列
select * from emp;
/* 使用 *(星号)的缺点:把不必要的列也查询出来了,而且效率不如直接指定列名 */
-- 17.查询emp表中的所有部门和职位
select dept,job from emp;
/* 思考:如果查询的结果中,存在大量重复的记录,如何剔除重复记录,只保留一条? */
-- distinct 用于剔除重复的记录
select distinct dept,job from emp;
3.3 WHERE子句查询
-- 18.查询emp表中薪资大于3000的所有员工,显示员工姓名、薪资
select name,sal from emp where sal>3000;
-- 19.查询emp表中总薪资(薪资+奖金)大于3500的所有员工,显示员工姓名、总薪资
select name,sal+bonus from emp where (sal+bonus)>3500;
/*任何值和null运算得null*/
-- ifnull(列, 值)函数: 判断指定的列是否包含null值, 如果有null值, 用第二个值替换null值
select name,sal+ifnull(bonus,0) from emp where (sal+ifnull(bonus,0))>3500;
/* 注意查看上面查询结果中的表头,思考如何将表头中的 sal+bonus 修改为 "总薪资"
其中as 可以省略,原名与别名之间用空格隔开*/
select name as 姓名,sal+ifnull(bonus,0) as 总薪资 from emp where (sal+ifnull(bonus,0))>3500;
/* 试一试:where中能使用定义好的别名吗?
where 中不能使用列别名
*/
-- 20.查询emp表中薪资在3000和4500之间的员工,显示员工姓名和薪资
select name,sal from emp where sal>=3000 and sal<=4500;
/* 提示: between...and...:在...之间 */
select name,sal from emp where sal between 3000 and 4500;
-- 21.查询emp表中薪资为 1400、1600、1800的员工,显示员工姓名和薪资
select name,sal from emp where sal=1400 or sal =1600 or sal=1800;
select name,sal from emp where sal in(1400,1600,1800);
-- 22.查询薪资不为1400、1600、1800的员工
select name,sal from emp where !(sal=1400 or sal=1600 or sal=1800);
select name,sal from emp where not sal in(1400,1600,1800);
select name,sal from emp where sal not in(1400,1600,1800);
-- 23.查询emp表中薪资大于4000和薪资小于2000的员工,显示员工姓名、薪资。
select name,sal from emp where sal>4000 or sal<2000;
-- 24.查询emp表中薪资大于3000并且奖金小于600的员工,显示员工姓名、薪资、奖金。
-- 处理null值
select name,sal,ifnull(bonus,0) from emp where sal>3000 and ifnull(bonus,0)<600;
-- 25.查询没有部门的员工(即部门列为null值)
select * from emp where dept is null;
/* 思考:如何查有部门的员工(即部门列不为null值) */
select * from emp where dept is not null;
3.4 Like模糊查询
-- 26.查询emp表中姓名中以"刘"开头的员工,显示员工姓名。
select name from emp where name like '刘%';
/* like进行模糊查询,"%" 表示通配,表示0或多个字符。"_"表示一个任意的字符 */
-- 27.查询emp表中姓名中包含"涛"员工,显示员工姓名。
select name from emp where name like '%涛%';
-- 28.查询emp表中姓名以"刘"开头并且姓名为2个字的员工,显示员工姓名。
select name from emp where name like '刘_';
4 分组查询、聚合函数、排序查询、分页查询
4.1 分组查询
-- 29.对emp表按照部门对员工进行分组,查看分组后效果
/* 分组的语法: select 查询的列 from 表名 group by 列名
根据指定的列进行分组 */
select * from emp group by dept;
select count(*) from emp;
-- 如果没有分组,(符合条件的)所有员工默认为一组
-- count(*) 统计结果有多少条记录,即统计所有员工人数每个组的人数
select dept,count(*) from emp group by dept;
-- 如果分了组,按组进行统计,统计每组有多少条记录,也就是统计每组人数
-- 30.对emp表按照职位进行分组, 并统计每个职位的人数, 显示职位和对应人数
select job,count(*) from emp group by job;
-- 31.对emp表按照部门进行分组, 求每个部门的最高薪资(不包含奖金),显示部门名称和最高薪资
select dept,max(sal) from emp group by dept;
-- 查询每个部门的最高薪资,显示部门,员工姓名,最高薪资
select emp.dept,name,t1.msal from emp,(select dept,max(sal) msal from emp group by dept) t1 where emp.dept=t1.dept and emp.sal=t1.msal;
4.2 聚合函数
-- 32.统计emp表中薪资大于3000的员工个数(- count(column)统计某列的行数)
select count(*) from emp where sal>3000;
-- 注意:聚合函数在统计时会自动剔除null值(即null不参与统计)
select count(bonus) from emp where sal>3000;
-- 由于bonus列中有null值,count函数会剔除null值在统计,所以结果是错的!
-- 33.统计emp表中所有员工的薪资总和(不包含奖金)(- sum(column)对某列的值求和)
select sum(sal) from emp;
-- 34.统计emp表员工的平均薪资(不包含奖金)(- avg(column)对某列的值求平均值)
select sum(sal)/count(*) from emp;
select avg(sal) from emp;
-- 35.查询emp表中所有在1993和1995年之间出生的员工,显示姓名、出生日期。
select name,birthday from emp where birthday between '1993-1-1' and '1995-12-31';
select name,birthday from emp where year(birthday) between 1993 and 1995;
-- year(date) 提取日期中的年份
-- month(date) 提取日期中的月份
-- day(date) 提取日期中的天数
-- 36.查询本月过生日的所有员工
/*
curdate() 获取当前日期 年月日
curtime() 获取当前时间 时分秒
sysdate() 获取当前日期+时间 年月日 时分秒 */
select * from emp where month(birthday)=month(curdate());
4.3 排序查询
/* order by 排序的列 asc 升序(从低到高)
order by 排序的列 desc 降序(从高到低) */
-- 37.对emp表中所有员工的薪资进行升序(从低到高)排序,显示员工姓名、薪资。
/* 默认就是升序,所以asc可以省略不写 */
select name,sal from emp order by sal asc;
-- 38.对emp表中所有员工奖金进行降序(从高到低)排序,显示员工姓名、奖金。
select name,ifnull(bonus,0) 奖金 from emp order by ifnull(bonus,0) asc;
select name,bonus from emp order by bonus desc;
4.4 分页查询
/* 在mysql中,通过limit进行分页查询:
limit (页码-1)*每页显示记录数, 每页显示记录数 */
-- 39.查询emp表中的所有记录,分页显示:每页显示3条记录,返回第 1 页。
select * from emp limit 0,3; -- 第一页 0可以省略,写成select * from emp limit 3;
-- 40.查询emp表中的所有记录,分页显示:每页显示3条记录,返回第 2 页。
select * from emp limit 3,3;
5 外键
5.1 新建数据库db20并插入数据
-- --------------------------------------------------
-- --------------------------------------------------
-- 创建db20库、dept表、emp表并插入记录
-- --------------------------------------------------
-- 删除db20库(如果存在)
drop database if exists db20;
-- 重新创建db20库
create database db20 charset utf8;
-- 选择db20库
use db20;
-- 删除部门表, 如果存在
drop table if exists dept;
-- 重新创建部门表, 要求id, name字段
create table dept(
id int primary key auto_increment, -- 部门编号
name varchar(20) -- 部门名称
);
-- 往部门表中插入记录
insert into dept values(null, '财务部');
insert into dept values(null, '人事部');
insert into dept values(null, '科技部');
insert into dept values(null, '销售部');
-- 删除员工表, 如果存在
drop table if exists emp;
-- 创建员工表, 要求id, name, dept_id
create table emp(
id int primary key auto_increment, -- 员工编号
name varchar(20), -- 员工姓名
dept_id int -- 部门编号
-- ,foreign key(dept_id) references dept(id)
);
insert into emp values(null, '张三', 1);
insert into emp values(null, '李四', 2);
insert into emp values(null, '老王', 3);
insert into emp values(null, '赵六', 4);
insert into emp values(null, '刘能', 4);
5.2 外键
-- 41.尝试删除dept表中的某一个部门
/* 上面的部门删除成功后,员工表里的某些员工就没有了对应的部门,
这种我们称之为数据的完整性被破坏了,
为了避免这种情况,可以在删除之前,查看将要删除的部门下是否还有员工存在,如果有就不要删除;
或者,让数据库帮我们去维护这样的对应关系,也就是当将要被删除的部门下如果还有员工,
就阻止删除操作,让数据库帮我们维护这样的对应关系,就需要指定外键。 */
-- 为已经存在的表添加外键
-- alert table 表名 add constraint FK_ID foreign key(外键字段名) references 外表表名(主键字段名)
alter table emp add constraint FK_ID foreign key(dept_id) references dept (id);
-- 42.重新创建db20中的dept和emp表,在创建时,指定emp表中的dept_id列为外键,即这一列要严格参考dept表中的id列, 再次尝试删除dept表中的某一个部门,查看是否能删除成功
-- MariaDB [db20]> insert into emp values(null,'张三',12);
-- ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`db20`.`emp`, CONSTRAINT `FK_ID` FOREIGN KEY (`dept_id`) REFERENCES `dept` (`id`))
-- 上述错误表示,若要向emp中插入数据,则必须插入已经在dept中存在的id值,实际意义就是要把新来的员工放入某个部门,则部门必须先存在。
6 关联查询、外连接查询
6.1 新建数据库db30并插入数据
-- --------------------------------------------------
-- --------------------------------------------------
-- 创建db30库、dept表、emp表并插入记录
-- --------------------------------------------------
-- 删除db30库(如果存在)
drop database if exists db30;
-- 重新创建db30库
create database db30 charset utf8;
-- 选择db30库
use db30;
-- 删除部门表, 如果存在
drop table if exists dept;
-- 重新创建部门表, 要求id, name字段
create table dept(
id int primary key auto_increment, -- 部门编号
name varchar(20) -- 部门名称
);
-- 往部门表中插入记录
insert into dept values(null, '财务部');
insert into dept values(null, '人事部');
insert into dept values(null, '科技部');
insert into dept values(null, '销售部');
-- 删除员工表, 如果存在
drop table if exists emp;
-- 创建员工表(员工编号、员工姓名、所在部门编号)
create table emp(
id int primary key auto_increment, -- 员工编号
name varchar(20), -- 员工姓名
dept_id int -- 部门编号
);
-- 往员工表中插入记录
insert into emp values(null, '张三', 1);
insert into emp values(null, '李四', 2);
insert into emp values(null, '老王', 3);
insert into emp values(null, '赵六', 5);
6.2 关联查询、外连接查询
-- 43.查询部门和部门对应的员工信息
select * from dept,emp;
-- 笛卡尔积查询:如果有两张表,其中一张表有m条数据,另外一张表有n条数据,笛卡尔积查询的结果是m*n条
-- 这种查询其中包含大量错误的数据,一般我们不会直接使用这种查询.
select * from dept,emp where dept.id = emp.dept_id;
/*
+----+--------+----+------+---------+
| id | name | id | name | dept_id |
+----+--------+----+------+---------+
| 1 | 财务部 | 1 | 张三 | 1 |
| 2 | 人事部 | 2 | 李四 | 2 |
| 3 | 科技部 | 3 | 老王 | 3 |
+----+--------+----+------+---------+*/
-- 通过关联条件,剔除大量错误的数据,保留正确的数据,这就是关联查询,其中where后面的条件就是关联条件.
-- 44.查询所有部门和部门下的员工,如果部门下没有员工,员工显示为null(一定要列出所有部门)
select * from dept left join emp on dept.id = emp.dept_id;
-- left join:左外连接查询,会将左边表中的所有数据都列出来,右边表只显示符合条件的记录
/*
+----+--------+------+------+---------+
| id | name | id | name | dept_id |
+----+--------+------+------+---------+
| 1 | 财务部 | 1 | 张三 | 1 |
| 2 | 人事部 | 2 | 李四 | 2 |
| 3 | 科技部 | 3 | 老王 | 3 |
| 4 | 销售部 | NULL | NULL | NULL |
+----+--------+------+------+---------+*/
-- 45.查询部门和所有员工,如果员工没有所属部门,部门显示为null
select * from dept right join emp on dept.id = emp.dept_id;
-- right join:右外连接查询,会将右边表中的所有数据都列出来,左边表只显示符合条件的记录
/*
+------+--------+----+------+---------+
| id | name | id | name | dept_id |
+------+--------+----+------+---------+
| 1 | 财务部 | 1 | 张三 | 1 |
| 2 | 人事部 | 2 | 李四 | 2 |
| 3 | 科技部 | 3 | 老王 | 3 |
| NULL | NULL | 4 | 赵六 | 5 |
+------+--------+----+------+---------+*/
-- 全外连接查询: (mysql不支持全外连接查询)
select * from dept full join emp on dept.id = emp.dept_id;-- 报错,mysql不支持全外连接查询
-- 扩展:查询出所有部门和所有员工,并列出部门和员工的对应关系,如果没有对应的,在另一方显示null
-- union 联合查询,将两个查询结果合并在一起显示,并去除重复的记录(模拟全外连接查询)
select * from dept left join emp on dept.id = emp.dept_id
union
select * from dept right join emp on dept.id = emp.dept_id;
/*
+------+--------+------+------+---------+
| id | name | id | name | dept_id |
+------+--------+------+------+---------+
| 1 | 财务部 | 1 | 张三 | 1 |
| 2 | 人事部 | 2 | 李四 | 2 |
| 3 | 科技部 | 3 | 老王 | 3 |
| 4 | 销售部 | NULL | NULL | NULL |
| NULL | NULL | 4 | 赵六 | 5 |
+------+--------+------+------+---------+*/
-- union all 和union作用大致相同,union all 不会去重!
select * from dept left join emp on dept.id = emp.dept_id
union all
select * from dept right join emp on dept.id = emp.dept_id;
/*
+------+--------+------+------+---------+
| id | name | id | name | dept_id |
+------+--------+------+------+---------+
| 1 | 财务部 | 1 | 张三 | 1 |
| 2 | 人事部 | 2 | 李四 | 2 |
| 3 | 科技部 | 3 | 老王 | 3 |
| 4 | 销售部 | NULL | NULL | NULL |
| 1 | 财务部 | 1 | 张三 | 1 |
| 2 | 人事部 | 2 | 李四 | 2 |
| 3 | 科技部 | 3 | 老王 | 3 |
| NULL | NULL | 4 | 赵六 | 5 |
+------+--------+------+------+---------+*/
7 子查询、多表查询
7.1 新建数据库db40并插入数据
-- --------------------------------------------------
-- --------------------------------------------------
-- 创建db40库、dept表、emp表并插入记录
-- --------------------------------------------------
-- 删除db40库(如果存在)
drop database if exists db40;
-- 重新创建db40库
create database db40 charset utf8;
-- 选择db40库
use db40;
-- 创建部门表
create table dept( -- 创建部门表
id int primary key, -- 部门编号
name varchar(50), -- 部门名称
loc varchar(50) -- 部门位置
);
-- 创建员工表
create table emp( -- 创建员工表
id int primary key, -- 员工编号
name varchar(50), -- 员工姓名
job varchar(50), -- 职位
topid int, -- 直属上级
hdate date, -- 受雇日期
sal int, -- 薪资
bonus int, -- 奖金
dept_id int, -- 所在部门编号
foreign key(dept_id) references dept(id)
);
-- 往部门表中插入记录
insert into dept values ('10', '培优部', '北京');
insert into dept values ('20', '就业部', '上海');
insert into dept values ('30', '大数据部', '广州');
insert into dept values ('40', '销售部', '深圳');
-- 往员工表中插入记录
insert into emp values ('1001', '王克晶', '办事员', '1007', '1980-12-17', '800', 500, '20');
insert into emp values ('1003', '齐雷', '分析员', '1011', '1981-02-20', '1900', '300', '10');
insert into emp values ('1005', '王海涛', '推销员', '1011', '1981-02-22', '2450', '600', '10');
insert into emp values ('1007', '刘苍松', '经理', '1017', '1981-04-02', '3675', 700, '20');
insert into emp values ('1009', '张慎政', '推销员', '1011', '1981-09-28', '1250', '1400', '10');
insert into emp values ('1011', '陈子枢', '经理', '1017', '1981-05-01', '3450', 400, '10');
insert into emp values ('1013', '张久军', '办事员', '1011', '1981-06-09', '1250', 800, '10');
insert into emp values ('1015', '程祖红', '分析员', '1007', '1987-04-19', '3000', 1000, '20');
insert into emp values ('1017', '韩少云', '董事长', null, '1981-11-17', '5000', null, null);
insert into emp values ('1019', '刘沛霞', '推销员', '1011', '1981-09-08', '1500', 500, '10');
insert into emp values ('1021', '范传奇', '办事员', '1007', '1987-05-23', '1100', 1000, '20');
insert into emp values ('1023', '赵栋', '经理', '1017', '1981-12-03', '950', null, '30');
insert into emp values ('1025', '朴乾', '分析员', '1023', '1981-12-03', '3000', 600, '30');
insert into emp values ('1027', '叶尚青', '办事员', '1023', '1982-01-23', '1300', 400, '30');
7.2 子查询、多表查询
-- db40库emp表数据
select * from emp;
/*
+------+--------+--------+-------+------------+------+-------+---------+
| id | name | job | topid | hdate | sal | bonus | dept_id |
+------+--------+--------+-------+------------+------+-------+---------+
| 1001 | 王克晶 | 办事员 | 1007 | 1980-12-17 | 800 | 500 | 20 |
| 1003 | 齐雷 | 分析员 | 1011 | 1981-02-20 | 1900 | 300 | 10 |
| 1005 | 王海涛 | 推销员 | 1011 | 1981-02-22 | 2450 | 600 | 10 |
| 1007 | 刘苍松 | 经理 | 1017 | 1981-04-02 | 3675 | 700 | 20 |
| 1009 | 张慎政 | 推销员 | 1011 | 1981-09-28 | 1250 | 1400 | 10 |
| 1011 | 陈子枢 | 经理 | 1017 | 1981-05-01 | 3450 | 400 | 10 |
| 1013 | 张久军 | 办事员 | 1011 | 1981-06-09 | 1250 | 800 | 10 |
| 1015 | 程祖红 | 分析员 | 1007 | 1987-04-19 | 3000 | 1000 | 20 |
| 1017 | 韩少云 | 董事长 | NULL | 1981-11-17 | 5000 | NULL | NULL |
| 1019 | 刘沛霞 | 推销员 | 1011 | 1981-09-08 | 1500 | 500 | 10 |
| 1021 | 范传奇 | 办事员 | 1007 | 1987-05-23 | 1100 | 1000 | 20 |
| 1023 | 赵栋 | 经理 | 1017 | 1981-12-03 | 950 | NULL | 30 |
| 1025 | 朴乾 | 分析员 | 1023 | 1981-12-03 | 3000 | 600 | 30 |
| 1027 | 叶尚青 | 办事员 | 1023 | 1982-01-23 | 1300 | 400 | 30 |
+------+--------+--------+-------+------------+------+-------+---------+*/
-- db40库dept表数据
select * from dept;
/*
+----+----------+------+
| id | name | loc |
+----+----------+------+
| 10 | 培优部 | 北京 |
| 20 | 就业部 | 上海 |
| 30 | 大数据部 | 广州 |
| 40 | 销售部 | 深圳 |
+----+----------+------+*/
-- 46.列出薪资比'王海涛'薪资高的所有员工,显示姓名、薪资
select name,sal from emp where sal>(select sal from emp where name='王海涛');
/*
+--------+------+
| name | sal |
+--------+------+
| 刘苍松 | 3675 |
| 陈子枢 | 3450 |
| 程祖红 | 3000 |
| 韩少云 | 5000 |
| 朴乾 | 3000 |
+--------+------+*/
-- 47.列出与'刘沛霞'从事相同职位的所有员工,显示姓名、职位、部门编号。
select name,job,dept_id from emp where job=(select job from emp where name='刘沛霞');
/*
+--------+--------+---------+
| name | job | dept_id |
+--------+--------+---------+
| 王海涛 | 推销员 | 10 |
| 张慎政 | 推销员 | 10 |
| 刘沛霞 | 推销员 | 10 |
+--------+--------+---------+*/
-- 子查询:将一个查询的结果作为另一个查询的条件.
-- 48.列出薪资比'大数据部'部门(已知部门编号为30)所有员工薪资都高的员工信息,显示员工姓名、薪资和部门名称。
-- (列出所有员工)
-- 左外连接查询,查询所有员工和员工对应的部门
select emp.name 姓名,sal 薪资,dept.name 部门 from emp left join dept
on emp.dept_id=dept.id
where sal>(select max(sal) from emp where dept_id=30);
/*
+--------+------+--------+
| 姓名 | 薪资 | 部门 |
+--------+------+--------+
| 陈子枢 | 3450 | 培优部 |
| 刘苍松 | 3675 | 就业部 |
| 韩少云 | 5000 | NULL |
+--------+------+--------+*/
-- 49.列出在'培优部'任职的员工,假定不知道'培优部'的部门编号, 显示部门名称,员工名称。
-- 关联查询两张表
select dept.name 部门,emp.name 姓名 from emp,dept where emp.dept_id = dept.id;
/*
+----------+--------+
| 部门 | 姓名 |
+----------+--------+
| 培优部 | 齐雷 |
| 培优部 | 王海涛 |
| 培优部 | 张慎政 |
| 培优部 | 陈子枢 |
| 培优部 | 张久军 |
| 培优部 | 刘沛霞 |
| 就业部 | 王克晶 |
| 就业部 | 刘苍松 |
| 就业部 | 程祖红 |
| 就业部 | 范传奇 |
| 大数据部 | 赵栋 |
| 大数据部 | 朴乾 |
| 大数据部 | 叶尚青 |
+----------+--------+*/
-- 求出在培优部的员工
select dept.name 部门,emp.name 姓名 from emp,dept
where emp.dept_id = dept.id and dept.name='培优部';
/*
+--------+--------+
| 部门 | 姓名 |
+--------+--------+
| 培优部 | 齐雷 |
| 培优部 | 王海涛 |
| 培优部 | 张慎政 |
| 培优部 | 陈子枢 |
| 培优部 | 张久军 |
| 培优部 | 刘沛霞 |
+--------+--------+*/
-- 50.(自查询)列出所有员工及其直接上级,显示员工姓名、上级编号,上级姓名
-- 列: e1.name , e2.id, e2.name
-- 表: emp 看做员工表,起一个别名 e1 / emp 看做上级表,起一个别名 e2
-- 关联条件:e1.topid = e2.id
select e1.name 员工姓名,e2.id 上级编号,e2.name 上级姓名
from emp e1,emp e2
where e1.topid =e2.id;
/*
+--------+----------+----------+
| 姓名 | 上级编号 | 上级姓名 |
+--------+----------+----------+
| 王克晶 | 1007 | 刘苍松 |
| 齐雷 | 1011 | 陈子枢 |
| 王海涛 | 1011 | 陈子枢 |
| 刘苍松 | 1017 | 韩少云 |
| 张慎政 | 1011 | 陈子枢 |
| 陈子枢 | 1017 | 韩少云 |
| 张久军 | 1011 | 陈子枢 |
| 程祖红 | 1007 | 刘苍松 |
| 刘沛霞 | 1011 | 陈子枢 |
| 范传奇 | 1007 | 刘苍松 |
| 赵栋 | 1017 | 韩少云 |
| 朴乾 | 1023 | 赵栋 |
| 叶尚青 | 1023 | 赵栋 |
+--------+----------+----------+*/
-- 拓展:查询所有员工及其对应上级(包含没有上级的员工)-- 使用左外连接查询!
select e1.name 员工姓名,e2.id 上级编号,e2.name 上级姓名
from emp e1 left join emp e2
on e1.topid =e2.id;
/*
+----------+----------+----------+
| 员工姓名 | 上级编号 | 上级姓名 |
+----------+----------+----------+
| 王克晶 | 1007 | 刘苍松 |
| 齐雷 | 1011 | 陈子枢 |
| 王海涛 | 1011 | 陈子枢 |
| 刘苍松 | 1017 | 韩少云 |
| 张慎政 | 1011 | 陈子枢 |
| 陈子枢 | 1017 | 韩少云 |
| 张久军 | 1011 | 陈子枢 |
| 程祖红 | 1007 | 刘苍松 |
| 韩少云 | NULL | NULL |
| 刘沛霞 | 1011 | 陈子枢 |
| 范传奇 | 1007 | 刘苍松 |
| 赵栋 | 1017 | 韩少云 |
| 朴乾 | 1023 | 赵栋 |
| 叶尚青 | 1023 | 赵栋 |
+----------+----------+----------+
*/
-- 51.列出最低薪资大于1500的各种职位,显示职位和该职位最低薪资
-- 求出各个职位的最低薪资
select job,min(sal)from emp
group by job;
/*
+--------+----------+
| job | min(sal) |
+--------+----------+
| 分析员 | 1900 |
| 办事员 | 800 |
| 推销员 | 1250 |
| 经理 | 950 |
| 董事长 | 5000 |
+--------+----------+*/
-- 求出最低薪资大于1500 的职位, 使用having 筛选
select job,min(sal) from emp
group by job
having min(sal)>1500;
/*
+--------+----------+
| job | min(sal) |
+--------+----------+
| 分析员 | 1900 |
| 董事长 | 5000 |
+--------+----------+*/
-- 52.列出在每个部门就职的员工数量、平均工资。显示部门编号、员工数量,平均薪资。
select dept_id ,count(*),avg(sal)
from emp group by dept_id;
/*
+---------+----------+-----------+
| dept_id | count(*) | avg(sal) |
+---------+----------+-----------+
| NULL | 1 | 5000.0000 |
| 10 | 6 | 1966.6667 |
| 20 | 4 | 2143.7500 |
| 30 | 3 | 1750.0000 |
+---------+----------+-----------+*/
-- 53.查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数。
-- 关联查询两张表(dept, emp)
select d.id,d.name,d.loc,e.name
from dept d,emp e
where d.id=e.dept_id;
/*
+----+----------+------+--------+
| id | name | loc | name |
+----+----------+------+--------+
| 10 | 培优部 | 北京 | 齐雷 |
| 10 | 培优部 | 北京 | 王海涛 |
| 10 | 培优部 | 北京 | 张慎政 |
| 10 | 培优部 | 北京 | 陈子枢 |
| 10 | 培优部 | 北京 | 张久军 |
| 10 | 培优部 | 北京 | 刘沛霞 |
| 20 | 就业部 | 上海 | 王克晶 |
| 20 | 就业部 | 上海 | 刘苍松 |
| 20 | 就业部 | 上海 | 程祖红 |
| 20 | 就业部 | 上海 | 范传奇 |
| 30 | 大数据部 | 广州 | 赵栋 |
| 30 | 大数据部 | 广州 | 朴乾 |
| 30 | 大数据部 | 广州 | 叶尚青 |
+----+----------+------+--------+*/
-- 替换要显示的列和统计部门人数
select d.id,d.name,d.loc,count(e.name)
from dept d,emp e
where d.id=e.dept_id
group by d.name;
/*
+----+----------+------+---------------+
| id | name | loc | count(e.name) |
+----+----------+------+---------------+
| 10 | 培优部 | 北京 | 6 |
| 30 | 大数据部 | 广州 | 3 |
| 20 | 就业部 | 上海 | 4 |
+----+----------+------+---------------+*/
-- 54.列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称。
/*
列: e1.id, e1.name, d.name
表: emp e1: 员工表
emp e2: 上级表
dept d: 部门表
关联条件: e1.topid=e2.id
e1.dept_id=d.id
筛选条件: e1.hdate<e2.hdate */
select e1.id,e1.name,d.name
from emp e1,emp e2,dept d
where e1.topid= e2.id
and e1.dept_id = d.id
and e1.hdate<e2.hdate;
-- 55.列出每个部门薪资最高的员工信息,显示部门编号、员工姓名、薪资
-- 查询emp表中所有员工的部门编号、姓名、薪资
select dept_id,name,sal from emp;
-- 查询emp表中每个部门的最高薪资,显示部门编号、最高薪资
select dept_id,max(sal) from emp
group by dept_id;
-- 第二次查询的结果作为一张临时表和第一次查询进行关联查询
select emp.dept_id,name,sal from emp,
(select dept_id,max(sal) maxsal from emp
group by dept_id) t1
where t1.dept_id =emp.dept_id
and emp.sal=t1.maxsal;
-- 求每个部门的最高薪资,显示部门名称和最高薪资(不能显示员工姓名)
补充
补充1、笛卡尔积查询:
笛卡尔积查询:如果同时查询两张表,左边表有m条数据,右边表有n条数据,那么笛卡尔积查询是结果就是 m*n 条记录。这就是笛卡尔积查询。例如:
select * from dept,emp;
上面的查询中包含大量错误的数据, 一般不使用这种查询。
如果只想保留正确的记录,可以通过where条件进行筛选,将符合条件的保留下来,不符合条件的自然就会被剔除,例如:
select * from dept,emp where dept.id=emp.dept_id;
补充2、左外连接和右外连接查询:
(1) 左外连接查询:是将左边表中所有数据都查询出来, 如果在右边表中没有对应的记录, 右边表显示为null即可。
(2) 右外连接查询:是将右边表中所有数据都查询出来, 如果在左边表中没有对应的记录, 左边表显示为null即可。
补充3、where和having都用于筛选过滤,但是:
(1) where用于在分组之前进行筛选, having用于在分组之后进行筛选
(2) 并且where中不能使用列别名, having中可以使用别名
(3) where子句中不能使用列别名(可以使用表别名), 因为where子句比select先执行!!
补充4、SQL语句的书写顺序和执行顺序:
SQL语句的书写顺序:
select…
from…
where…
group by…
order by…
…
SQL语句的执行顺序:
from… – 确定要查询的是哪张表 (定义表别名)
where… – 从整张表的数据中进行筛选过滤
select… – 确定要显示哪些列 (定义列别名)
group by… – 根据指定的列进行分组
order by… – 根据指定的列进行排序
…
======================================