1. 创建db数据库 并且使用 如果有先删除再创建
create database db2;
use db2;
2. 在db2中创建员工表(emp)字段:员工编号(empno),员工姓名(ename)
create table emp (empno int,ename varchar(10));
3. 修改表名为t_emp
rename table emp to t_emp;
4. 在表中添加工资sal字段在最后
alter table t_emp add sal int;
5. 在员工姓名的前面添加年龄字段
alter table t_emp add age int after empno;
6. 在员工姓名的后面添加部门字段(dept 字符串类型)
alter table t_emp add dept varchar(10) after ename;
7. 添加刘关张和取经四人组共7个人 年龄随意,工资5000以内随意,刘关张为三国部,师徒四人为取经部
insert into t_emp values
(1,28,'刘备','三国部',2500),
(2,25,'关羽','三国部',3500),
(3,18,'张飞','三国部',4500),
(4,28,'悟空','取经部',1500),
(5,65,'八戒','取经部',1200),
(6,28,'吴京','取经部',3200),
(7,8,'唐僧','取经部',500);
8.把取经部门的所有人改成1000岁
update t_emp set age=1000 where dept='取经部';
9. 删除工资低于2000的人
delete from t_emp where sal<2000;
10. 查询三国部所有人的名字
select ename from t_emp where dept='三国部';
1. 查询emp表中出现的所有职位
select distinct job from emp;
1. 查询工资小于等于1600的所有员工姓名和工资
select ename,sal from emp
where sal<=1600;
2. 查询部门编号是20的所有员工姓名、职位job和部门编号deptno
select ename,job,deptno from emp
where deptno=20;
3. 查询职位是manager的所有员工姓名和职位
select ename,job from emp
where job='manager';
4. 查询部门不是10号部门的所有员工姓名和部门编号使用两种方式实现
select ename,deptno from emp
where deptno!=10;
select ename,deptno from emp
where deptno<>10;
5. 查询t_item表中单价price等于23的商品信息
select * from t_item
where price=23;
6. 查询t_item表中单价不等于8443的商品信息
select * from t_item
where price!=8443;
- and 和java中的&&效果一样
- or 和java中的||效果一样
1. 查询不是10号部门并且工资小于3000的员工信息
select * from emp
where deptno!=10 and sal<3000;
2. 查询部门编号为30或者上级领导为7698的员工姓名,职位,上级领导和部门编号
select ename,job,mgr,deptno from emp
where deptno=30 or mgr=7698;
1. 查询emp表中工资为5000,1500,3000的员工信息
select * from emp where sal=5000 or sal=1500 or sal=3000;
select * from emp where sal in (5000,1500,3000);
- 对多行数据进行统计:
- 求和:sum(字段名)
举例:emp中工资总和
select sum(sal) from emp;
- 平均值:avg(字段名)
select avg(sal) from emp where deptno=10;
- 最大值:max(字段名)
select max(sal) from emp where deptno=10;
- 最小值:min(字段名)
select min(sal) from emp where deptno=10;
- 统计数量:count(*)
select count(*) from emp where sal<1000;
1. 案例:查询没有上级领导的员工的编号,姓名,工资
select empno,ename,sal from emp
where mgr is null;
2. 案例:查询emp表中没有奖金的员工的姓名,职位,工资,以及奖金
select ename,job,sal,comm from emp
where comm is null;
3. 案例:查询emp表中含有奖金的员工的编号,姓名,职位,以及奖金
select ename,job,sal,comm from emp
where comm is not null;
4. 案例:查询含有上级领导的员工的姓名,工资以及上级领导的编号
select ename,sal,mgr from emp
where mgr is not null;
5. 案例:查询emp表中名字以‘S’开头的所有员工的姓名
select ename from emp
where ename like 's%';
6. 案例:查询emp表中名字的最后一个字符是'S'的员工的姓名
select ename from emp
where ename like '%s';
7. 案例:查询倒数的第2个字符是‘E’的员工的姓名
select ename from emp
where ename like '%e_';
8. 案例:查询emp表中员工的倒数第3个字符是‘N’的员工姓名
select ename from emp
where ename like '%n__';
9. 案例:查询emp表中员工的名字中包含‘A’的员工的姓名
select ename from emp
where ename like '%a%';
10. 案例:查询emp表中名字不是以'K'开头的员工的所有信息
select ename from emp
where ename not like 'k%';
11. 案例:查询emp表中名字中不包含‘A’的所有员工的信息
select ename from emp
where ename not like '%a%';
12. 案例:做文员的员工人数(job= CLERK 的)
select count(*) from emp
where job='clerk';
13. 案例:销售人员 job: SALESMAN 的最高薪水
select max(sal) from emp
where job='salesman'
14. 案例:最早和最晚入职时间
select min(hiredate),max(hiredate) from emp
15. 案例:查询类别 163的商品总库存量
select sum(num) from t_item
where category_id=163;
16. 案例:查询 类别 163 的商品
select * from t_item
where category_id=163;
17. 案例:查询商品价格不大于100的商品名称列表
select title from t_item
where price<=100;
18. 案例:查询品牌是联想,且价格在40000以上的商品名称和价格
select title,price from t_item
where title like '%联想%'
and price>40000;
19. 案例:查询品牌是三木,或价格在50以下的商品名称和价格
select title,price from t_item
where title like '%三木%' or price<50;
20. 案例:查询品牌是三木、广博、齐心的商品名称和价格
select title,price from t_item
where title like '%三木%'
or title like '%广博%'
or title like '%齐心%'
21. 案例:查询品牌不是联想、戴尔的商品名称和价格
select title,price from t_item
where title not like '%联想%'
and title not like '%戴尔%';
22.案例:查找品牌是联想且价格大于10000的电脑名称
select title from t_item
where title like '%联想%'
and price>10000 and title like '%电脑%';
23. 案例:查询联想或戴尔的电脑名称列表
select title from t_item
where title like '%联想%'
or title like '%戴尔%'
24. 案例:查询联想、戴尔、三木的商品名称列表
select title from t_item
where title like '%联想%'
or title like '%戴尔%'
or title like '%三木%'
25. 案例:查询不是戴尔的电脑名称列表
select title from t_item
where title not like '%戴尔%'
26. 案例:查询所有是记事本的名称和价格
select title,price from t_item
where title like '%记事本%';
27. 案例:查询品牌是末尾字符是'力'的商品的名称和价格
select title,price from t_item
where title like '%力';
29.案例:查询卖点含有'赠'产品名称
select title from t_item
where sell_point like '%赠%';
30.案例:查询emp表中员工的编号,姓名,职位,工资,并且工资在1000~2000之间。
select empno,ename,job,sal from emp
where sal between 1000 and 2000;
31.案例:查询emp表中员工在10号部门,并且含有上级领导的员工的姓名,职位,上级领导编号以及所属部门的编号
select ename,job,mgr,deptno from emp
where deptno=10 and mgr is not null;
32.案例:查询emp表中名字中包含'E',并且职位不是MANAGER的员工的编号,姓名,职位,以及工资
select empno,ename,job,sal from emp
where ename like '%e%'
and job!='manager';
33.案例:查询emp表中10号部门或者20号部门中员工的编号,姓名,所属部门的编号
select empno,ename,deptno from emp
where deptno=10 or deptno=20;
34.案例:查询emp表中没有奖金或者名字的倒数第2个字母不是T的员工的编号,姓名,职位以及奖金
select empno,ename,job,comm from emp
where comm is null
or ename not like '%t_';
35.案例:查询工资高于3000或者部门编号是30的员工的姓名,职位,工资,入职时间以及所属部门的编号
select ename,job,sal,hiredate,deptno from emp
where sal>3000 or deptno=30;
36.案例:查询不是30号部门的员工的所有信息
select * from emp where deptno!=30;
37.案例:查询奖金不为空的员工的所有信息
select * from emp where comm is not null;
38.案例:查询emp表中所有员工的编号,姓名,职位,根据员工的编号进行降序排列
select empno,ename,job from emp
order by empno desc;
39.案例:查询emp表中部门编号是10号或者30号中,所有员工姓名,职务,工资,根据工资进行升序排列
select ename,job,sal,deptno from emp
where deptno=10 or deptno=30
order by sal;
40.案例:查询emp表中所有的数据,然后根据部门的编号进行升序排列,如果部门编号一致,根据员工的编号进行降序排列
select * from emp order by deptno, empno desc;
41.案例:查询emp表中工资高于1000或者没有上级领导的员工的编号,姓名,工资,所属部门的编号,以及上级领导的编号,根据部门编号进行降序排列,如果部门编号一致根据工资进行升序排列。
select empno,ename,sal,deptno,mgr from emp
where sal>1000 or mgr is null
order by deptno desc, sal;
42.案例:查询emp表中名字中不包含S的员工的编号,姓名,工资,奖金,根据工资进行升序排列,如果工资一致,根据编号进行降序排列
select empno,ename,sal,comm from emp
where ename not like '%s%'
order by sal,empno desc;
43.案例:统计emp表中员工的总数量
select count(*) from emp;
44.案例:统计emp表中获得奖金的员工的数量
select count(*) from emp
where comm is not null and comm>0;
45.案例:求出emp表中所有的工资累加之和
select sum(sal) from emp;
46.案例:求出emp表中所有的奖金累加之和
select sum(comm) from emp;
47.案例:求出emp表中员工的平均工资
select avg(sal) from emp;
48.案例:求出emp表中员工的平均奖金
select avg(comm) from emp;
49.案例:求出emp表中员工的最高工资
select max(sal) from emp;
50.案例:求出emp表中员工编号的最大值
select max(empno) from emp;
51.案例:查询emp表中员工的最低工资。
select min(sal) from emp;
52.案例:查询emp表中员工的人数,工资的总和,平均工资,奖金的最大值,奖金的最小值,并且对返回的列起别名。
select count(*) 人数,sum(sal) 工资总和,avg(sal) 平均工资, max(comm) 奖金最大值, min(comm) 奖金最小值 from emp;
53. 案例:查询emp表中每个部门的编号,人数,工资总和,最后根据人数进行升序排列,如果人数一致,根据工资总和降序排列。
select deptno,count(*),sum(sal) from emp
group by deptno
order by count(*),sum(sal) desc;
54. 案例:查询工资在1000~3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排列。
select deptno,avg(sal),min(sal),max(sal) from emp
where sal between 1000 and 3000
group by deptno
order by avg(sal);
55. 案例:查询含有上级领导的员工,每个职业的人数,工资的总和,平均工资,最低工资,最后根据人数进行降序排列,如果人数一致,根据平均工资进行升序排列
select job,count(*) c,sum(sal),avg(sal) a,min(sal) from emp
where mgr is not null
group by job
order by c desc,a;
56.案例:查询工资在1000~3000之间每一个员工的编号,姓名,职位,工资
select empno,ename,job,sal from emp
where sal between 1000 and 3000;
57.案例:查询emp表中奖金在500~2000之间所有员工的编号,姓名,工资以及奖金
select empno,ename,comm,sal from emp
where comm between 500 and 2000;
58.案例:查询员工的编号是7369,7521,
select * from emp
where empno in (7369,7521);
59.案例:查询emp表中,职位是ANALYST,
select * from emp
where job='analyst';
60.案例:查询emp表中职位不是ANALYST,
select * from emp
where job!='analyst';
1. 查询每个部门的平均工资,要求平均工资大于2000。
- 以下为错误语法: where后面不能写聚合函数
select deptno,avg(sal) a from emp where a>2000 group by deptno;
- 使用having 2,having写在group by 后面
- where后面写普通字段的过滤条件,having后面写聚合函数的过滤条件
select deptno,avg(sal) a from emp
group by deptno
having a>2000;
1. 查询每个分类商品的库存总量,高于199999的库存总量
select category_id,sum(num) s from t_item
group by category_id
having s>199999;
2. 查询每个分类商品所对应的平均单价,要求平均单价低于100
select category_id,avg(price) a from t_item
group by category_id
having a<100;
3. 查询分类id为238和917两个分类的平均单价
select category_id,avg(price) from t_item
where category_id in(238,917)
group by category_id;
4. 查询emp表中每个部门的平均工资高于2000的部门编号,部门人数,平均工资,最后根据平均工资降序排序
select deptno,count(*),avg(sal) a from emp
group by deptno
having a>2000
order by a desc;
5. 查询emp表中工资在1000-3000之间的员工,每个部门的编号,工资总和,平均工资,过滤掉平均工资低于2000的部门,按照平均工资升序排序
select deptno,sum(sal),avg(sal) a from emp
where sal between 1000 and 3000
group by deptno
having a>=2000 order by a;
6. 查询emp表中名字不是以s开头,每个职位的名字,人数,工资总和,最高工资,过滤掉平均工资是3000的职位,根据人数升序排序,如果一致根据工资总和降序排序
select job,count(*) c,sum(sal) s,max(sal) from emp where ename not like 's%'
group by job
having avg(sal)!=3000
order by c,s desc;
7. 查询emp表 每年入职的人数(提高题)
select extract(year from hiredate) year,count(*) from emp group by year;
取出created字段中包含的年月日;
select extract(year from created) cYear,extract(month from created),extract(day from created) from tb_item;
1. 查询emp表中工资最高的员工信息
select max(sal) from emp;
select * from emp where sal=5000;
- 将以上两条合并成一条sql
select * from emp where sal=(select max(sal) from emp);
2. 查询emp表中工资超过平均工资的所有员工信息
select * from emp where sal>(select avg(sal) from emp);
3. 查询工资高于20号部门平均工资的员工信息
select * from emp where sal>(select avg(sal) from emp where deptno=20);
4. 查询和Jones相同工作的其它员工信息
select job from emp where ename='jones';
select * from emp where job=(select job from emp where ename='jones') and ename!='jones';
5. 查询工资最低的员工的相同部门的员工信息
select min(sal) from emp;
select deptno from emp where sal=(select min(sal) from emp);
select * from emp where deptno=(select deptno from emp where sal=(select min(sal) from emp));
- having 要和 group by 结合使用
6. 查询最后入职的员工信息
select * from emp where hiredate=(select max(hiredate) from emp);
7. 查询姓名为king的部门编号和部门名称(需要使用dept表)
select deptno from emp where ename='king';
select deptno,dname from dept where deptno=(select deptno from emp where ename='king');
8. 查询有商品的分类id和分类名称(有商品 就是在商品表中出现的分类,需要使用t_item_category表)
- 先从商品表中得到所有的分类id
select distinct category_id from t_item;
- 从分类表中查询id等于上面结果的分类信息
select id,name from t_item_category
where id in(select distinct category_id from t_item);
9. 查询有员工的部门信息
select distinct deptno from emp;
select * from dept where deptno in(select distinct deptno from emp);
10. 扩展(难度最高):查询平均工资最高的部门信息
- 得到最高的平均工资
select avg(sal) a from emp group by deptno order by a desc limit 0,1;
- 通过最高的平均工资 得到 部门的编号
select deptno from emp
group by deptno
having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1);
- 通过部门编号得到部门信息
select * from dept where deptno in(select deptno from emp
group by deptno
having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1));
(in适合内外表都很大的情况,exists适合外表结果集很小的情况)
- 同时查询多张表的数据称为关联查询
1. 查询每一个员工的姓名和对应的部门名称
select e.ename,d.dname
from emp e,dept d
where e.deptno=d.deptno;
2. 查询在纽约工作的所有员工的信息
select e.*
from emp e,dept d
where e.deptno=d.deptno and d.loc='new york';
###笛卡尔积
- 关联查询如果不写关联关系,则查询结果为两张表的乘积,这个乘积称为 笛卡尔积
- 笛卡尔积是一种错误的查询结果,工作中切记不要出现
###等值连接和内连接
1. 等值连接:
select * from A,B
where A.x=B.x and A.age=18
2. 内连接 用的更多
select * from A join B
on A.x=B.x
where A.age=18;
- 查询每个员工的姓名和对应的部门名称
select e.ename,d.dname
from emp e join dept d
on e.deptno=d.deptno;
外连接
- 左外连接: 以join 左边表为主表 左边表显示所有数据右边交集数据
select e.ename,d.dname
from emp e left join dept d
on e.deptno=d.deptno;
- 右外连接: 以join 右边表为主表 右边表显示所有数据左边交集数据
select e.ename,d.dname
from emp e right join dept d
on e.deptno=d.deptno;
练习
1. 每个部门的人数,根据人数排序
select deptno,count(*) c from emp
gourp by deptno
order by c;
2. 每个部门中,每个主管的手下人数
select deptno,mgr,count(*) from emp
where mgr is not null
group by deptno,mgr;
3. 每种工作的平均工资
select job,avg(sal) from emp
group by job;
4. 每年的入职人数
select extract(year from hiredate) year,count(*) from emp
group by year;
5. 少于等于3个人的部门信息
- 先得到部门人数
select deptno,count(*) c from emp
group by deptno having c<=3;
子查询:
select * from dept where deptno in (select deptno from emp
group by deptno having count(*)<=3);
- 内连接:把第一步的结果当成张新表
select d.*
from dept d join (select deptno,count(*) c from emp
group by deptno having c<=3) n
on d.deptno=n.deptno;
6. 拿最低工资的员工信息
select * from emp where sal=(select min(sal) from emp);
7. 只有一个下属的主管信息
- 得到主管编号
select mgr from emp
group by mgr having count(*)=1;
- 通过得到的编号查询员工信息
select * from emp where empno in(select mgr from emp
group by mgr having count(*)=1);
7. 只有一个员工的部门信息
select deptno from emp
group by deptno having count(*)=1;
select * from dept where deptno in(select deptno from emp
group by deptno having count(*)=1);
8. 平均工资最高的部门编号
select deptno from emp
group by deptno order by avg(sal) desc
limit 0,1;
9. 下属人数最多的人,查询其个人信息,考虑并列第一的问题
- 得到下属人数 并且取出最多的 人数 5
select count(*) from emp
group by mgr order by count(*) desc
limit 0,1;
- 通过得到的人数 查询哪个主管下属是这个数
select mgr from emp
group by mgr having count(*)=(select count(*) from emp
group by mgr order by count(*) desc
limit 0,1);
-查询个人信息
select * from emp where empno in(上面内容);
select * from emp where deptno in (select deptno from emp group by mgr having count(*)=(select count(*) from emp group by mgr order by count(*) desc limit 0,1));
10. 拿最低工资的人的信息
select * from emp where sal=(select min(sal) from emp);
11. 最后入职的员工信息
select * from emp where hiredate=(select max(hiredate) from emp);
12. 工资多于平均工资的员工信息
select * from emp where sal>(select avg(sal) from emp);
13. 查询员工信息,部门名称
select e.*,d.dname
from emp e join dept d
on e.deptno=d.deptno
14. 员工信息,部门名称,所在城市
select e.*,d.dname,d.loc
from emp e join dept d
on e.deptno=d.deptno
15. DALLAS 市所有的员工信息
- 子查询:
select deptno from dept where loc='dallas';
select * from emp where deptno=(select deptno from dept where loc='dallas');
- 内连接:
select e.*
from emp e join dept d
on e.deptno=d.deptno
where d.loc='dallas';
16. 按城市分组,计算每个城市的员工数量
select d.loc,count(*)
from emp e join dept d
on e.deptno=d.deptno
group by d.loc;
17. 查询员工信息和他的主管姓名
select e.*,m.ename
from emp e join emp m
on e.mgr = m.empno;
18. 员工信息,员工主管名字,部门名
select e.ename,m.ename,d.dname
from emp e join emp m
on e.mgr = m.empno
join dept d
on e.deptno=d.deptno;
20. 员工和他所在部门名
select e.*,d.dname
from emp e join dept d
on e.deptno=d.deptno;
21. 案例:查询emp表中所有员工的姓名以及该员工上级领导的编号,姓名,职位,工资
select e.ename,e.mgr,m.ename,m.job,m.sal
from emp e left join emp m
on e.mgr=m.empno;
22. 案例:查询emp表中名字中没有字母'K'的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址
select e.empno,e.ename,e.job,d.deptno,d.dname,d.loc
from emp e left join dept d
on e.deptno=d.deptno
where e.ename not like '%k%';
23. 案例:查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资
select d.*,e.empno,e.ename,e.job,e.sal
from dept d left join emp e
on d.deptno=e.deptno;
练习
1.创建两张表
2.创建trade交易流水表(id,time,money,type,pid)
create database db6;
use db6;
create table trade(id int primary key auto_increment,
time date,money int,type varchar(5),pid int);
3.创建person人物表(id,name,gender,rel)
create table person(id int primary key auto_increment,
name varchar(10),gender varchar(5),rel varchar(5));
4.插入数据
insert into person values(null,'刘德华','男','亲戚'),
(null,'杨幂','女','亲戚'),
(null,'马云','男','同事'),
(null,'特朗普','男','朋友'),
(null,'貂蝉','女','朋友');
insert into trade values(null,'2018-03-20',-20,'微信',1),
(null,'2018-02-20',500,'现金',2),
(null,'2018-05-20',-50,'现金',2),
(null,'2018-03-21',50000,'支付宝',3),
(null,'2018-03-22',-5,'支付宝',3),
(null,'2018-03-26',2000,'微信',4),
(null,'2018-04-22',-20000,'微信',5);
5.统计2018年2月15号到现在的所有红包收益
select sum(money) from trade where time>strtodate('2018年2月15号','%Y年%c月%d号');
select sum(money) from trade where time>str_to_date('2018年2月15号','%Y年%c月%d号');
select sum(money) from trade where time>'2018-02-15';
6.查询2018年2月15号到现在 金额大于100所有女性亲戚的名字和红包金额
select p.name,t.money from trade t join person p on
t.pid=p.id where t.money not between -100 and 100
and t.time>strtodate('2018年2月15号','%Y年%c月%d号') and p.gender='女' and p.rel='亲戚';
select p.name,t.money from trade t join person p on
t.pid=p.id where t.money>100
and t.time>"2018-2-15" and p.gender='女' and p.rel='亲戚';
7.查询三个平台分别收入的红包金额
select type,sum(money) from trade
where money>0 group by type;