回顾
* where
=
<>
> >= < <=
like % _
between ... and ...
in
is null
not between ... and ...
not in
is not null
* order by
order by a,b
order by a desc, b asc
* distinct
去除重复
select distinct a,b ...
* 函数
字符串、数字、日期、加密
* 多行函数
count(),max(),min(),avg(),sum()
group by 子句
========================================
* 求多行函数时, 用 group by 分组计算
1 张三 30
2 李四 30 30部门 3 人
3 王五 30
4 赵六 70
5 钱七 70 70部门 2 人
select department_id,count(*) from emp
group by department_id
having 子句
===============================================
* 多行函数分组计算,
对多行函数结果进行过滤,
不能用 where,而使用 having 代替
*) where 过滤普通条件
*) having 过滤多行函数结果
子查询
================================================
* 用一个查询的结果,
作为另一个查询的过滤条件
select id,name,sal...
from ...
where sal=(select min(sal) from...);
* 单值子查询
=
<>
>
* 多值子查询
in
> all(1,2,3,4) 大于最大值
> any(1,2,3,4) 大于最小值
行内视图
==============================================
* 从一个查询的查询结果再查询
select ... from (select ... from...) tb
多表连接查询
===============================================
* 用外键将多张表连接成一张大表
select
a.xx,a.xx,a.xx,
b.xx,b.xx
from a, b
where
a.id = b.xid
* 自连接
*)外键与本表中的主键连接
*)将一张表看做是两张表
* 标准 sql 连接语法
上面非标准语法,多数数据库都支持
select ...
from
a inner join b on a.id=b.xid
inner join c on c.id=a.xid
[inner] join d on ...
[inner] join e on ...
*) 左外链接、右外链接
a left [outer] join b on ...
将左表 a 中连接条件之外的数据也查出来
a right [outer] join b on ...
将右表 b 中连接条件之外的数据也查出来
练习
======================================
1. 每个部门的人数
select department_id,count(1) c
from employees
where department_id is not null
group by department_id
order by c;
2. 每个部门中,每个主管的手下人数
部门 主管id 手下
1 1 3
1 2 5
1 3 2
2 4 6
2 5 1
select department_id,manager_id,count(1) c
from employees
where department_id is not null and
manager_id is not null
group by department_id,manager_id
order by
department_id,c;
3. 每种工作的平均工资
select job_id,avg(salary)
from employees
group by job_id;
4. 每年的入职人数
select extract(year from hire_date) year,count(*) c
from employees
group by year
order by c;
5. 只有一个人的部门
select department_id,count(*) c
from employees
where department_id is not null
group by department_id
having c=1; -- 对多行函数结果进行过滤
6. 拿最低工资的员工信息
select
employee_id,first_name,salary
from employees
where salary=
(select min(salary) from employees);
7. 只有一个下属的主管信息
100 张三
110 李四
120 王五 100
130 赵六 110
select
employee_id,first_name,salary
from employees
where employee_id in (
select manager_id
from employees
where manager_id is not null
group by manager_id
having count(*)=1;
);
select manager_id
from employees
where manager_id is not null
group by manager_id
having count(*)=1;
8. 平均工资最高的部门编号
1.分组求平均
2.得到最高平均工资
1.
select department_id, avg(salary)
from employees
where department_id is not null
group by department_id;
2.
select max(avg)
from (
select department_id, avg(salary) avg
from employees
where department_id is not null
group by department_id
) a;
select department_id, avg(salary) avg
from employees
where department_id is not null
group by department_id
order by avg desc
limit 1;
9. 下属人数最多的人,查询其个人信息
1. 得到下属最多的人他的 id
2. 用 id 过滤查询他的个人信息
1.
select manager_id
from employees
where manager_id is not null
group by manager_id
order by count(*) desc
limit 1;
2.
select employee_id,first_name,salary
from employees
where employee_id=(
select manager_id
from employees
where manager_id is not null
group by manager_id
order by count(*) desc
limit 1
);
10.
拿最低工资的人的信息
select
employee_id,first_name,salary
from employees
where salary=(
select min(salary)
from employees
);
11. 最后入职的员工信息
select
employee_id,first_name,salary,hire_date
from employees
where hire_date=(
select max(hire_date) from employees
);
12. 工资多于平均工资的员工信息
select
employee_id,first_name,salary
from employees
where salary>(
select avg(salary) from employees
);
13. 部门表
select * from departments;
14. 查询员工信息,部门名称
select
e.employee_id,e.first_name,e.salary,
d.department_id,d.department_name
from employees e, departments d
where e.department_id=d.department_id;
15. 查询部门信息,和部门经理的信息
select
d.department_id,d.department_name,d.manager_id,
e.employee_id,e.first_name,e.salary
from departments d, employees e
where d.manager_id=e.employee_id;
17. 地区表
select * from locations;
18. 员工信息,部门名称,所在城市
1 张三 7000 销售 纽约
select
e.employee_id,e.first_name,e.salary,
d.department_name,
l.city
from
employees e,
departments d,
locations l
where
e.department_id=d.department_id and
d.location_id=l.location_id;
19. Seattle 市所有的员工信息
1 张三 7000
select
e.employee_id,e.first_name,e.salary,
d.department_name
from
employees e,
departments d,
locations l
where
e.department_id=d.department_id and
d.location_id=l.location_id and
l.city='Seattle';
20. 按城市分组,计算每个城市的员工数量
Beijing 12
Seattle 18
...
select
l.city, count(*) c
from
employees e,
departments d,
locations l
where
e.department_id=d.department_id and
d.location_id=l.location_id
group by
l.city
order by c;
22. 查询员工信息和他的主管姓名
1 张三
2 李四
3 王五 1 张三
4 赵六 1 张三
5 钱七 2 李四
select
e1.employee_id,e1.first_name,e1.salary,
e2.first_name mgr_name
from
employees e1,
employees e2
where
e1.manager_id=e2.employee_id;
23. 员工信息,员工主管名字,部门名
1 张三
2 李四
3 王五 1 张三 销售
4 赵六 1 张三 销售
5 钱七 2 李四 IT
select
e1.employee_id,e1.first_name,e1.salary,
e2.first_name mgr_name,
d.department_name
from
employees e1,
employees e2,
departments d
where
e1.manager_id=e2.employee_id and
e1.department_id=d.department_id;
24. 员工信息,部门名,和部门经理
select
e1.employee_id,e1.first_name,e1.salary,
d.department_name,
e2.first_name mgr_name
from
employees e1,
departments d,
employees e2
where
e1.department_id=d.department_id and
d.manager_id=e2.employee_id;
25. 用户信息,工作岗位,直接上司名,部门名,城市,国家,州
select * from jobs;
select * from locations;
select * from countries;
select * from regions;
select
e1.employee_id,e1.first_name,e1.salary,
j.job_title,
e2.first_name mgr_name,
d.department_name,
l.city,
c.country_name,
r.region_name
from
employees e1
join jobs j on e1.job_id=j.job_id
join employees e2 on e1.manager_id=e2.employee_id
join departments d on e1.department_id=d.department_id
join locations l on d.location_id=l.location_id
join countries c on l.country_id=c.country_id
join regions r on c.region_id=r.region_id;
26. 员工和他所在部门名,没有部门显示 null
select
e.employee_id,e.first_name,e.salary,
d.department_name
from
employees e
left join departments d
on e.department_id=d.department_id;
作业
==================================================
4.2.14
用户地址表 (tb_address)
Is_default 后面加两个字段
user_id bigint 外键
status tinyint
4.2.6
内容表(tb_content)
4.2.7
内容分类表(tb_content_category)
工资多于工种 IT_PROG 平均工资的员工
select
employee_id,first_name,salary
from
employees
where
salary>(select avg(salary) from employees where job_id='IT_PROG');
平均工资最高的工种, 显示工作全名
select
job_id,job_title
from
jobs
where
job_id=(
select job_id
from employees
group by job_id
order by avg(salary) desc
limit 1
);
------------
select
e.job_id,j.job_title,avg(salary) avg
from
employees e join jobs j on e.job_id=j.job_id
group by e.job_id,j.job_title
order by avg desc
limit 1;
每个部门拿最高工资的人
1.每个部门的最高工资
2.再用这些工资过滤
select
employee_id,first_name,salary,department_id
from employees
where (department_id,salary)=(60, 9000);
select
employee_id,first_name,salary,department_id
from employees
where (department_id,salary) in(
select
department_id, max(salary)
from employees
where department_id is not null
group by department_id
);
每年第一个入职的人
1.每年最小入职时间
2.用这些时间过滤
select
employee_id,first_name,salary,hire_date
from employees
where hire_date in(
select min(hire_date)
from employees
group by extract(year from hire_date)
);
外连接,查询全部27个部门,有部门经理显示经理名
select
d.department_id,d.department_name,
e.first_name
from
departments d left join employees e
on d.manager_id=e.employee_id;