MYSQL_DQL语言的学习(3)

DQL(数据查询)语言的学习(3)

在这里插入图片描述
注意:以上为employees表、departments表、locations表、job_grades表、jobs表*

目录

  1. 子查询
    1.1 where或having后面
    1.2 select后面
    1.3 from后面
    1.4 exists后面

1、子查询

含义:出现在其他语句中的select语句,称为子查询或内查询。
注意:外面的语句可以是insert、update、delete、select等,一般select作为外面语句较多
外面如果为select语句,则此语句称为外查询或主查询

分类:
1、按子查询出现的位置:
select后面:
仅仅支持标量子查询
from后面:
支持表子查询
where或having后面 ☆
标量子查询
列子查询
行子查询
exists后面(相关子查询)
表子查询

2、按结果集的行列数不同:
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)
表子查询(结果集一般为多行多列)

**

一、where或having后面

**
1、 标量子查询(单行子查询)
2、 列子查询(多行子查询)
3、 行子查询(多列多行)
特点:
(1) 子查询放在小括号内
(2) 子查询一般放在条件的右侧
(3) 标量子查询,一般搭配着单行操作符使用【< > = <= >= <>】
列子查询,一般搭配着多行操作符使用
in,any/some,all
(4)子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果

#标量子查询
案例1:谁的工资比Abel高
1、查询Abel的工资

select salary from employees where last_name='Abel';

2、查询员工的信息,满足salary>1结果

select * from employees where salary>(select salary from employees where last_name='Abel');

案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id和工资
1、查询141号员工的job_id

select job_id from employees where employees_id=141;

2、查询143号员工的salary

select salary from employees where employees_id=143;

3、查询员工的姓名,job_id和工资,要求job_id=1并且salary>2

select name,job_id,salary 
from employees 
where salary>( select salary from employees where employees_id=143) 
and job_id=( select job_id from employees where employees_id=141);

案例3:返回公司工资最少的员工的last_name,job_id和salary
1、查询公司的最低工资

select min(salary) from employees;

2、查询last_name,job_id和salary,要求salary=1

select last_name,job_id,salary 
from employees 
where salary=select min(salary) from employees);

案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资
1、查询50号部门的最低工资

select min(salary) from employees where department_id=50;

2、 查询每个部门的最低工资

select min(salary),department_id 
from employees 
group by department_id;

3、在2基础上筛选,满足min(salary)>1

select min(salary),department_id 
from employees 
group by department_id 
having min(salary)>select min(salary) from employees where department_id=50;

注意:非法使用标量子查询的情况
1、 子查询的结果为多个结果,不是一个结果
2、 子查询的筛选条件有误

#列子查询(多行子查询)
操作符 含义
IN/NOT_IN : 等于列表中的任意一个
ANY|SOME : 和子查询返回的某一个值比较
ALL: 和子查询返回的所有值比较

案例1:返回location_id是1400或1700的部门中的所有员工姓名
1、查询location_id是1400或1700的部门编号

select distinct department_id 
from employees 
where location_id in1400,1700;

2、查询所有员工姓名,部门号是1

select name 
from employees 
where department_id in( select department_id from employees where location_id in(1400,1700));

案例2:返回其他工种中比job_id为’IT_PROG’部门任一工资低的员工的员工号、姓名、job_id以及salary
1、查询job_i为为’IT_PROG’的工资

select distinct salary from employees where job_id='IT_PROG';

2、 查询每个部门的工资比1小的信息

select employee_id,last_name,job_id,salary 
from employees 
where salary < any(select distinct salary from employees where job_id='IT_PROG') 
and job _id <>'IT_PROG';

select employee_id,last_name,job_id,salary 
from employees 
where salary < max(select max(salary) from employees where job_id='IT_PROG')
and job _id <>'IT_PROG';

案例3:返回其他工种中比job_id为’IT_PROG’部门所有工资低的员工的员工号、姓名、job_id以及salary

select employee_id,last_name,job_id,salary 
from employees 
where salary < all(select distinct salary from employees where job_id= 'IT_PROG') 
and job _id <>'IT_PROG';

select employee_id,last_name,job_id,salary 
from employees 
where salary < (select min(salary) from employees where job_id='IT_PROG') 
and job _id <>'IT_PROG';

#行子查询(结果集一行多列或多行多列)
案例:查询员工编号最小且工资最高的员工信息

方法一、

select * from employees 
where (employee_id,salary)=(select min(employee_id),max(salary) from employees);

方法二、
1、查询员工编号最小

select min(employee_id) from employees ;

2、查询工资最高的员工

select max(salary) from employees;

3、查询1、2合并条件的员工信息

select * from employees 
where employee_id=( select min(employee_id) from employees)
and salary=( select max(salary) from employees);

**

#二、select后面

**
案例1:查询每个部门的员工个数

select d.*,(select count(*) from employees where e.department_id=d.department_id) '个数'
from departments d;

案例2:查询员工工号=102的部门名
方法一:

select deparment_name 
from employees e,department d 
where e.employees_id=102 and e.department_id = d.department_id;

方法二:

select (select department_name from departemnts d inner join employees e on d.department_id=e.department_id where e.employees_id=102 );

#三、from后面

注意:将子查询结果充当一张表,要求必须起别名

案例:查询每个部门的平均工资的工资等级
1、查询每个部门的平均工资

select avg(salary),department_id 
from employees 
group by department_id;

2、(2)连接(1)的结果集合job_grades表,筛选条件平均工资 between lowest_sal and highest_sal

select avg_d.*,g.grade_level 
from (select avg(salary) ag,department_id 
from employees group by department_id) avg_d 
inner join job_grades g 
on avg_d.ag between lowest_sal and hightest_sal;

#四、exists后面(相关子查询)

语法: exists(完整的查询语句)
结果: 1或0

select exists(select employee_id from employees);

案例1:查询有员工的部门号
方式一 exists:

select department_name 
from departments d 
where exists(select * from employees e where e.department_id=d.department_id);

方式二in:

select department_name 
from departments d 
where d.department_id in(select * from employees);

案例2:查询没有女朋友的男生信息

方式一:
select b.* from boys b where b.id not in(select * from girls);
方式二:
select b.* from boys b where not exists(select * from girls g where b.id=g.boy_id);

练习:

案例1:查询和zlotkey相同部门的员工姓名和工资
1、查询zlotkey的所在部门

select department_id from employees where last_name='zlotkey';

2、查询部门号=1的员工姓名和工资

select last_name,salary 
from employees 
where department_id=( select department_id from employees where last_name='zlotkey');

案例2:查询工资比公司平均工资高的员工的员工号,姓名和工资
1、查询公司平均工资

select avg(salary) avg_sal from employees;

2、查询salary>1的员工号,姓名和工资

select employee_id,last_name,salary 
from employees where salary>( select avg(salary)avg_sal from employees);

案例3:查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资
1、查询各部门的平均工资

select avg(salary),department_id 
from employees 
group by department_id;

2、2连接1结果集合employees表,进行筛选

select e.department_id,e.last_name,e.salary 
from (select avg(salary) ag,department_id from employees group by department_id) avg_dep 
inner join employees e on avg_dep.department_id=e.department_id
where salary> avg_dep.ag;

案例4:查询姓名中包含字母u的员工在相同部门的员工的员工号和姓名
1、查询姓名中包含字母u的员工部门号

select distinct department_id 
from employees 
where last_name like '%u%';

2、查询与部门号=1中任意一个的员工姓名和工号

select last_name,employee_id 
from employees where department_id in (select distinct department_id from employees where last_name like '%u%');

案例5:查询在部门的location_id为1700的部门工作的员工的员工号
1、查询location_id为1700的部门

select department_id from departments where location_id=1700;

2、查询部门号等于1中的任意一个的员工号

select employees_id 
from employees 
where department_id = any(select department_id from departments where location_id=1700);

案例6:查询管理者是King的员工姓名和工资
1、查询姓名为King的员工号

select employee_id from employees where last_name='King';

2、查询哪个员工的manger_id=1;

select employee_id,salary 
from employees 
where manger_id in(select employee_id from employees where last_name=’King’);

案例7:查询工资最高的员工的姓名,要求first_name和last_name显示为一列,列名为姓.名

select concat(frist_name,last_name) '姓.名' 
from employees where salary=(select max(salary) from employees);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值