好孕美宝价格多少█微信 号█:138★0226★9370█好孕美宝价格多少 ████ █助孕包成功█ ★█100%包男孩█ ★█
含义:
出现在其他语句中(不仅仅是放在select语句中,在其它增删改中都可以用,只是用在查询中是最多的)的select语句,称为子查询或内查询
外部的查询语句,称为主查询语句,称为主查询或外查询。
示例: SELECT first_name FROM employees WHERE
department_id IN (SELECT department_id FROM departments
WHERE location_id=1700)
分类:
按子查询出现的位置:
select后面:
仅仅只支持标量子查询
from 后面:
支持表子查询(只要是个结果集就行)
where或having后面:♦ --侧重点
标量子查询 ♣
列子查询 ♣
行子查询(用的较少)
exists后面(称为:相关子查询):
表子查询(结果集)
按结果集的行列数不同:
标量子查询(又称为:单行子查询)(结果只有一行一列):
列子查询(又称:多行子查询)(结果集只有一列多行):
行子查询(结果集有一行多列):
表子查询(结果集一般为多行多列):
一.where或having后面
1.标量子查询(单行子查询)
2.列子查询(单行子查询)
3.行子查询(有很多列,很多行)
特点:
1.子查询放在小括号内
2.子查询一般放在条件的右侧
3.标量子查询,一般搭配着单行操作符,其实就是条件运算符(> < >= <= = <>)使用
列子查询,一般搭配着多行操作符(常见的有:IN,ANY/SOME,ALL)使用
4.子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果
#1.标量子查询
#案列1:谁的工资比Abel高?
#(1)查询Abel的工资
select salary
from employees
where last_name = ‘Abel‘
#(2)查询员工的信息,满足salary>(1结果)
select *
from employees
where salary>( #直接放where salary > 11000。这种被称为硬编码,如果(1)中Abel的工资变了,这种情况就不对了,还得修改
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 employee_id = 141
#(2)查询员工号为143号的员工的工资
select salary
from employees
where employee_id = 143
#(3)查询员工 姓名,job_id和工资
select concat(first_name,‘-‘,last_name) as 姓名,job_id,salary
from employees
where job_id = (
select job_id #这里只能select job_id这一个columns。多了会报错:Error Code:1241.Operand should contain 1 columns(1) . 如果查询的不是job_id 这个
from employees #column,不会报错,但查不到任何内容如图:这里是将job_id改为first_name得到的结果:
where employee_id = 141)
and salary > (
select salary
from employees
where employee_id = 143
);
#案例3:返回工资最少的员工的last_name,job_id和salary
#(1)查询工资最少的员工的工资
select min(salary)
from employees
#(2)查询员工的last_name,job_id和salar
select last_name,job_id,salary
from employees
where salary = (
select min(salary)
from employees
);
#案例4:查询最低工资大于50号部门最低工资的部门和其最低工资
#(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
);
#非法使用标量子查询
select min(salary),department_id
from employees
group by department_id
having min(salary)>(
select min(salary) #如果是select salary。因为50号部门的员工的工资有很多。明明这儿应该用标量子查询,但是这儿用到了列子查询(多行子查询)。报错:Error Code:1242.Subquery returns more than 1 row.(子查询返回超过1row)
from employees
where department_id = 50 #如果选择一个不存在的部门:where department_id = 250(不存在值为250的department_id)。不报错,但这也属于非法使用。结果:
);
#2.列子查询(多行子查询) #因为他的结果是一列多行
#案列1:返回location_id是1400或1700的部门中的所有员工姓名
#(1)查询location_id是1400或1700的部门编号
select department_id
from departments
where location_id in (1400,1700);
#(2)查询员工姓名,要求部门编号是(1)列表中的某一个
子查询实现:
select concat(first_name,‘-‘,last_name) as name,distinct department_id
from employees
where department_id in (
select department_id
from departments
where location_id in (1400,1700)
);
join实现:
select concat(employees.first_name,‘-‘,employees.last_name) as name,employees.department_id
from employees
inner join departments
on employees.department_id = departments.department_id
where location_id in (1400,1700)
#案列2:返回其它工种中(不包括‘IT_PROG‘)比job_id为‘IT_PROG‘任一工资低的员工的:工号,姓名,job_id,及salary
#(1)查询job_id为‘IT_PROG‘部门任一工资
select distinct salary
from employees
where job_id = ‘IT_PROG‘;
#(2)查询员工号,姓名,job_id以及salary,salary<any((1))的任意一个
select last_name,employee_id,job_id,salary
from employees
where salary<any(
select distinct salary
from employees
where job_id = ‘IT_PROG‘
) and job_id <> ‘IT_PROG‘;
#或
select last_name,employee_id,job_id,salary
from employees
where salary<any(
select max(salary)
from employees
where job_id = ‘IT_PROG‘
) and job_id <> ‘IT_PROG‘;
#案列3:返回其它工种中(不包括‘IT_PROG‘)比job_id为‘IT_PROG‘所有工资低的员工的:工号,姓名,job_id,及salary
select last_name,employee_id,job_id,salary
from employees
where salary < all(
select distinct salary
from employees
where job_id = ‘IT_PROG‘
) and job_id <> ‘IT_PROG‘;
#或
select last_name,employee_id,job_id,salary
from employees
where salary < (
select min(salary)
from employees
where job_id = ‘IT_PROG‘
) and job_id <> ‘IT_PROG‘;
#3.行子查询(结果集一行多列或多行多列)
select * #行子查询:将多个字段(employee_id和salary),当成了一个虚拟的字段((employee_id,salary))来用
from employees
where (employee_id,salary) = ( #用得不多,有局限性,要求两个筛选条件,或者更多的筛选条件都用的是=
select min(employee_id),max(salary)
from employees
)
#(1)查询最小的员工编号
select min(employee_id)
from employee
#(2)查询最高工资
select max(salary)
from employees
#(3)查询员工信息
select *
from employees
where employee_id = (
select min(employee_id)
from employees
) and salary = (
select max(salary)
from employees
);
#二,放在select后面的子查询
#案例:查询每个部门的员工个数
select d.*,(
select count(*)
from employees e
where e.department_id = d.department_id
) as 个数
from departments d;
#案例2:查询员工号=102的部门名
select (
select department_name
from departments d
inner join employees e
on d.department_id = e.department_id
where e.employee_id = 102
) as 部门名;
#三,from后面
将子查询结果充当一张表,要求必须其别名
#案例:查询每个部门的平均工资的工资等级
#(1)查询每个部门的平均工资
select avg(salary),department_id
from employees
group by department_id
select * from job_grades;
#(2)连接(1)的结果集和job_grades表,筛选条件平均工资between lowest_sal and highest
select ag_dep.*,g.grade_level
from (
select avg(salary) ag,department_id
from employees
group by department_id
) ag_dep
inner join job_grades g
on ag_dep.ag between lowest_sal and highest_sal
#四、exists后面的子查询(相关子查询)
/*
语法:
exists(完整的查询语句)
结果:
1或0
*/
select exists(select empooyee_id from employees); #exists(是否存在,bool类型)只关心(select empooyee_id from employees)中是否有值,有值为1,没有值为0
select exists(select employee_id from employees where salary = 300000);
#案例1:查询有员工名的部门名
select department_name
from departments d
where exists(
select *
from employees e
where d.department_id = e.department_id
);
#案例2:查询没有女朋友的男神信息
#in
select bo.*
from boys bo
where bo.id not in(
select boyfriend_id
from beauty
);
#exists
select bo.*
from boys bo
where not exists(
select boyfriend_id
from beauty b
where bo.id = b.boyfriend_id
);
原文地址:https://www.cnblogs.com/jingyinbaobei01/p/10566638.html