常见SQL查询实践
-
准备工作(执行如下地址对应的sql脚本-人力资源系统) gitee.com/JasonCN2008...
-
相关表设计说明
- 区域表(Regions) :一个区域可以有多个国家(countries)
- 国家表(Countries):一个国家可以有多个城市,街道地址(locactions)
- 地址表(Locations):一个locations可以有多个部门.
- 部门表(Departments):一个部门可以有多个雇员
- 雇员表(Employees):一个雇员对应一个岗位信息
- 岗位表(Jobs):一个岗位可以对应多个雇员
- 岗位历史变更表(job_history):雇员可能会有岗位的变更.
-
查询雇员编号为206的经理人的名字和薪水?
sql
select first_name,salary
from employees
where employee_id=(
select manager_id
from employees
where employee_id=206
)
- 查询雇员编号为206的雇员的名字和薪水以及他经理人的名字和薪水?
sql
select e1.first_name,e1.salary,e2.first_name,e2.salary
from employees e1 join employees e2
on e1.manager_id=e2.employee_id
where e1.employee_id=206
- 查询雇员编号为206的雇员所在部门的部门名称以及这个部门所在的城市?
方案1:
sql
select d.department_name,l.city
from employees e1 join departments d on e1.department_id=d.department_id
join locations l on d.location_id=l.location_id
where e1.employee_id=206
方案2:
sql
select d.department_name,l.city
from employees e1 join departments d join locations l
on e1.department_id=d.department_id and d.location_id=l.location_id
where e1.employee_id=206
- 查询雇员编号为206的雇员薪资,岗位名称,以及岗位对应的最低和最高薪资.
sql
select e1.employee_id,e1.salary,j.job_title,j.min_salary,j.max_salary
from employees e1 join jobs j
on e1.job_id=j.job_id
where e1.employee_id=206
- 查询公司每年入职的人数?
sql
select year(hire_date),count(*)
from employees
group by year(hire_date)
- 查询雇员表中佣金为null的雇员名名字和薪水
sql
select first_name,salary
from employees
where commission_pct is null;
- 查询每个部门的平均薪资,部门id为null的除外,平均薪资低于10000的除外,并按薪资降序排序;
sql
select department_id,avg(salary)
from employees
where department_id is not null
group by department_id
having avg(salary)>=10000
order by avg(salary) desc
- 求每个雇员的薪资并标注薪资等级,大于等于10000的为A,大于等于8000小于10000的为B,小于8000的为C;
sql
select first_name,salary,case when salary>=10000 then 'A'
when salary>=8000 then 'B'
else 'C' end
from employees
- 统计薪资大于10000的,薪资小于8000的雇员人数? (考查case when 表达式应用) 方案1:
sql
select sum(case when salary>10000 then 1 else 0 end) '大于10000',
sum(case when salary<8000 then 1 else 0 end) '小于8000'
from employees
方案2:
sql
select count(case when salary>10000 then 1 else null end) '大于10000',
count(case when salary<8000 then 1 else null end) '小于8000'
from employees
记住,count()函数统计数据时,只统计非null值.
- 统计每个部门的雇员人数,只显示人数最多的前三个部门信息即可.
sql
select department_id,count(*)
from employees
group by department_id
order by 2 desc
limit 3
- 请问同一个层次结构中,SQL语句的执行顺序是怎样?
sql
select [7]
from [1]
join [3]
on [2]
where [4]
group by [5]
having [6]
order by [8]
limit [9]
- 删除区域表(Regions)中区域名重复的记录,只保留区域id值最小的记录. 执行删除操作
方案1:(10.5.17-MariaDB支持,MySQL5.7、MySQL8.0不支持这种方案-并发更新可能会存在问题)
sql
delete
from regions
where region_id not in (
select min(region_id)
from regions
group by region_name
);
方案2: MySQL5.7支持
sql
delete
from regions
where region_id not in (
select min_id
from
(
select min(region_id) min_id
from regions
group by region_name
) r );
方案3: 多表关联(有重复字段名的,留id值最小的记录)
sql
delete r2.*
from regions r1 join regions r2
on r1.region_name=r2.region_name
where r1.region_id<r2.region_id
视图在数据库中的设计及应用?
-
何为视图(View)? 可以将视图理解为虚拟表,视图中只有结构,不存储数据,所有数据都存储在实际表中.但是,我们可以通过视图查看表中数据.基于视图可以简化对复杂SQL语句的反复编写,同时对外屏蔽直接对基表(实际的表)访问,提高系统表的安全.
-
如何创建视图(View)?
sql
create view t_emp_view
as
select e.employee_id,e.first_name,d.department_name,l.city
from employees e join departments d join locations l
on e.department_id=d.department_id and d.location_id=l.location_id
where e.employee_id=206
- 通过视图查询数据?
sql
select * from t_emp_view;
- 如何删除视图?
sql
drop view t_emp_view;