sql复习(set运算符、高级子查询)

一、set运算符

set操作符
union:得到两个查询结果的并集,并且⾃动去掉重复⾏。不会排序
union all:得到两个查询结果的并集,不会去掉重复⾏。也不会排序
intersect:得到两个查询结果的交集,并且按照结果集的第⼀个列进⾏排序
minus:得到两个查询结果的减集,以第⼀列进⾏排序

--查询部门的部门号,其中不包括job_id是”ST_CLERK”的部门号
select department_id
from departments
minus
select department_id
from employees
where job_id = 'ST_CLERK'
--查询10,50,20号部门的job_id,department_id
--并且department_id按10,50,20的顺序排列
column a_dummy noprint	--隐藏后面的1、2、3(序列号)

select job_id,department_id,1 a_dummy
from employees
where department_id = 10
union
select job_id,department_id,2
from employees
where department_id = 50
union
select job_id,department_id,3
from employees
where department_id = 20
order by 3	--使用order by对结果集排序
--查询所有员工的last_name ,department_id 和department_name
select last_name,department_id,to_char(null) department_name
from employees
union
select to_char(null),department_id,department_name
from departments

二、高级子查询

1.多列子查询

多列子查询中的比较分为两种:成对比较、不成对比较

成对比较

--查询与141号或174号员工的manager_id和department_id相同的
--其他员工的employee_id, manager_id, department_id
select employee_id,manager_id,department_id
from employees
where (manager_id,department_id) in (
                                     select manager_id,department_id
                                     from employees
                                     where employee_id in (141,174)
                                       )
and employee_id not in (141,174)

不成对比较

select employee_id,manager_id,department_id
from employees
where manager_id in (
                     select manager_id
                     from employees
                     where employee_id in (141,174)
                    )
and department_id in (
                     select department_id
                     from employees
                     where employee_id in (141,174)
                      )
and employee_id not in (141,174)

2.在 FROM 子句中使用子查询

案例对比:

--返回比本部门平均工资高的员工的last_name, department_id, salary及平均工资
select last_name,department_id,salary,
(select avg(salary) from employees e3 where e1.department_id = e3.department_id group by department_id) avg_sal
from employees e1
where salary > (
               select avg(salary)
                from employees e2
                where e1.department_id = e2.department_id
                group by department_id
               )
--在 FROM 子句中使用子查询
--返回比本部门平均工资高的员工的last_name, department_id, salary及平均工资
select last_name,e1.department_id,salary,e2.avg_sal
from employees e1,(select department_id,avg(salary) avg_sal from employees group by department_id) e2
where e1.department_id = e2.department_id
and e1.salary > e2.avg_sal

由上可知,在 FROM 子句中使用子查询可以减少冗余

3.单列子查询

<1>在 CASE 表达式中使用单列子查询

--显示员工的employee_id,last_name和location。
--其中,若员工department_id与location_id为1800的department_id相同,则location为’Canada’
--其余则为’USA’。
select employee_id,last_name,
(case department_id when (select department_id from departments where location_id = 1800) then 'Canada'
                    else 'USA' end) location
from employees

<2>在 ORDER BY 子句中使用单列子查询

--查询员工的employee_id,last_name,要求按照员工的department_name排序
select employee_id,last_name
from employees e
order by (select department_name
          from departments d
          where e.department_id = d.department_id) asc

4.相关子查询

子查询中使用主查询中的列,主查询的每一行都执行一次子查询

--查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id
select last_name,salary,department_id
from employees e1
where salary > (
               select avg(salary)
               from employees e2
               where e1.department_id = e2.department_id
               )
--若employees表中employee_id与job_history表中employee_id相同的数目不小于2,
--输出这些相同id的员工的employee_id,last_name和其job_id
select employee_id,last_name,job_id
from employees e
where 2 <= (
           select count(1)
           from job_history
           where e.employee_id = employee_id 
           )

5.EXISTS操作符和NOT EXISTS操作符

EXISTS 操作符检查在子查询中是否存在满足条件的行
如果满足条件则输出
NOT EXISTS操作符正好相反

--查询公司管理者的employee_id,last_name,job_id,department_id信息
select employee_id,last_name,job_id,department_id
from employees mgr
where exists(
                    select 'A'
                    from employees emp
                    where mgr.employee_id = emp.manager_id
                    )
--查询departments表中,不存在于employees表中的部门的department_id和department_name
select department_id,department_name
from departments d
where not exists(
            select 'A'
            from employees
            where department_id = d.department_id
            )

6.WITH 子句

使用 WITH 子句, 可以避免在 SELECT 语句中重复书写相同的语句块
WITH 子句将该子句中的语句块执行一次并存储到用户的临时表空间中
使用 WITH 子句可以提高查询效率

--查询公司中各部门的总工资大于公司中各部门的平均总工资的部门信息
with dept_sumsal as(
select department_name,sum(salary) sum_sal
from employees e,departments d
where e.department_id = d.department_id
group by department_name
),
dept_avgsal as(
select sum(sum_sal)/count(1) avg_sum_sal
from dept_sumsal
)

select *
from dept_sumsal
where sum_sal > (
                select avg_sum_sal
                from dept_avgsal
                )
order by department_name
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值