首页 > 技术文章 > 高级子查询

afangfang 2020-03-25 15:32 原文

书写多列子查询

在from子句中使用查询

在sql中使用单列子查询

书写相关子查询

使用exists 和no exists操作符

使用子查询更新和删除数据

使用with字句

 

 

-- 多列子查询:

--查询与141号或174相同的manager_id和department_id 相同的其他员工的employee_id,manager_id,department_id

select employee_id,manager_id,department_id
from employees e
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);

-- 改写为多列

select employee_id,manager_id,department_id
from employees e
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);

 

-- 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;
LAST_NAME                 DEPARTMENT_ID     SALARY    AVG_SAL
------------------------- ------------- ---------- ----------
King                                 90      24000 19333.33333 
Kochhar                              90      17000 19333.33333 
De Haan                              90      17000 19333.33333 
Hunold                               60       9000       5760 

 

--单列子查询

--显示员工的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 'Canda' else  'USA' end) location
from employees;   

 

--在order by中使用单列子查询

--查询员工的employeed_id ,last_name  要求按照员工的department_name排序

 

select employee_id,last_name
from employees  e1
order by(
          select  department_name
          from departments d
          where e1.department_id = d.department_id
          );

 

EMPLOYEE_ID LAST_NAME               
----------- -------------------------
        205 Higgins                   
        206 Gietz                     
        200 Wha_len                   
        101 Kochhar          

 

相关子查询

 

--  相关子查询: 按照一行接一行的顺序执行,主查询的每一行都执行一次子查询

 

 

 

 

-- 若employees表中employee_id与job-history表中employee_id相同的数目不小于2,

-- 输出这些相同id的员工的employee_id,last_name和其job_id

select employee_id,last_name,job_id
from employees e1
where 2<=(
          select count(*)
          from job_history
          where employee_id = e1.employee_id
);
EMPLOYEE_ID LAST_NAME                 JOB_ID   
----------- ------------------------- ----------
        101 Kochhar                   AD_VP      
        176 Taylor                    SA_REP     
        200 Wha_len                   AD_ASST    

 

 --查询departments表中, 不存在employees表中的部门的department_id和department_name

select department_id ,department_name
from departments d
where not exists(
                select 'x'
                from employees
                where department_id = d.department_id
         );
DEPARTMENT_ID DEPARTMENT_NAME              
------------- ------------------------------
          220 NOC                            
          170 Manufacturing                  
          240 Government Sales   

 

--相关更新

--相关删除

delete from 
emp22
where department_id in (
                        select department_id
                        from emp33
                        where department_id = emp22.department_id
);

 

 

with字句 提高查询效率

--查询公司各部门的总工资大于公司中各部门的平均总工资的部门信息

with dept_sumsal as(
select department_name,sum(salary) sum_sal
from departments d,employees e 
where d.department_id  = e.department_id
group by department_name
),
dept_avgsal as(
select sum(sum_sal)/count(*) avg_sum_sal
from dept_sumsal
)
select * 
from  dept_sumsal
where sum_sal>(
               select avg_sum_sal
               from dept_avgsal
            )
order by department_name;
DEPARTMENT_NAME                   SUM_SAL
------------------------------ ----------
Sales                              328300 
Shipping                           156400 

 

练习:

--查询员工的last_name,depatment_id,salary其中员工的salary,department_id与有奖金的任何一个员工的salary,department_id相同即可

select last_name,department_id,salary
from employees
where(salary,department_id) in (
                                select salary,department_id
                                from employees
                                where commission_pct is not null                              
                                );
LAST_NAME                 DEPARTMENT_ID     SALARY
------------------------- ------------- ----------
Vishney                              80      10500 
Zlotkey                              80      10500 

 

推荐阅读