likes
comments
collection
share

常见SQL查询实践

作者站长头像
站长
· 阅读数 5

常见SQL查询实践

  • 准备工作(执行如下地址对应的sql脚本-人力资源系统) gitee.com/JasonCN2008…

  • 相关表设计说明

    • 区域表(Regions) :一个区域可以有多个国家(countries)
    • 国家表(Countries):一个国家可以有多个城市,街道地址(locactions)
    • 地址表(Locations):一个locations可以有多个部门.
    • 部门表(Departments):一个部门可以有多个雇员
    • 雇员表(Employees):一个雇员对应一个岗位信息
    • 岗位表(Jobs):一个岗位可以对应多个雇员
    • 岗位历史变更表(job_history):雇员可能会有岗位的变更.
  • 查询雇员编号为206的经理人的名字和薪水?

select first_name,salary
from employees
where employee_id=(
  select manager_id
  from employees
  where employee_id=206
)
  • 查询雇员编号为206的雇员的名字和薪水以及他经理人的名字和薪水?
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:

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:

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的雇员薪资,岗位名称,以及岗位对应的最低和最高薪资.
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
  • 查询公司每年入职的人数?
select year(hire_date),count(*)
from employees
group by year(hire_date)
  • 查询雇员表中佣金为null的雇员名名字和薪水
select first_name,salary
from employees
where commission_pct is null;
  • 查询每个部门的平均薪资,部门id为null的除外,平均薪资低于10000的除外,并按薪资降序排序;
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;
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:
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:

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值.

  • 统计每个部门的雇员人数,只显示人数最多的前三个部门信息即可.
select department_id,count(*)
from employees
group by department_id
order by 2 desc
limit 3
  • 请问同一个层次结构中,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不支持这种方案-并发更新可能会存在问题)

delete
from regions
where region_id not in (
   select min(region_id)
   from regions
   group by region_name
);

方案2: MySQL5.7支持

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值最小的记录)

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)?

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
  • 通过视图查询数据?
select * from t_emp_view;
  • 如何删除视图?
drop view t_emp_view;