(数据库)10_子查询

一、子查询

将一条完成的查询语句作为另一个查询语句的一部分

--谁的工资比 Abel 高
select * from employees where salary >(
select salary from employees where  last_name = 'Abel');

二、子查询语法

SELECT  select_list
FROM  table
WHERE  expr operator
     (SELECT  select_list
          FROM  table);
  1. 子查询 (内查询) 在主查询之前一次执行完成
  2. 子查询的结果被主查询(外查询)使用

注意事项:

  1. 子查询要包含在括号内
  2. 将子查询放在比较条件的右侧
  3. 单行操作符对应单行子查询,多行操作符对应多行子查询。

三、子查询类型

select * from employees
where salary =(select min(salary) from employees)
and
hire_date =(select min(hire_date) from employees);
-- 查询 工资低于平均工资的雇员信息
select * from employees 
where salary <
(select avg(salary) from employees); 
select * from employees
where department_id in
(select department_id from departments where location_id = 1700);

1.单行子查询

只返回一行。
使用单行比较操作符。

在这里插入图片描述

--题目:返回job_id与141号员工相同,salary比143号员工多的
--员工  姓名,job_id 和工资
select first_name,last_name,job_id,salary 
from employees
where job_id = (select job_id from employees where employee_id =141)
and salary > (select salary from employees where employee_id =143)

1.1.在子查询中使用组函数

题目:返回公司工资最少的员工的last_name,job_id和salary
--返回公司工资最少的员工的last_name,job_id和salary
select last_name,job_id,salary 
from employees
where salary = (select min(salary) from employees);

1.2.子查询中的 HAVING 子句

首先执行子查询。
向主查询中的HAVING 子句返回结果

题目:查询最低工资大于50号部门最低工资的部门id和其最低工资

--题目:查询最低工资大于50号部门最低工资的部门id和其最低工资
select department_id,min(salary)
from employees
group by department_id
having min(salary) > (select min(salary) from employees where department_id =50);

2.非法使用子查询

SELECT employee_id, last_name
FROM   employees
WHERE  salary =
                (SELECT   MIN(salary)
                 FROM     employees
                 GROUP BY department_id);

在这里插入图片描述
多行子查询使用单行比较符

3.子查询中的空值问题

SELECT last_name, job_id
FROM   employees
WHERE  job_id =
                (SELECT job_id
                 FROM   employees
                 WHERE  last_name = 'Haas');

子查询不返回任何行

4.多行子查询

返回多行。
使用多行比较操作符。

在这里插入图片描述

4.1.在多行子查询中使用 ANY 操作符

ANY 小于子查询中的任意一个

--题目:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的
--员工的员工号、姓名、job_id 以及salary
select employee_id,last_name,job_id,salary
from employees
where salary < any(
select salary from employees where job_id ='IT_PROG')

4.2.在多行子查询中使用 ALL 操作符

ALL 小于所有的 那就是比最小的还小

扫描二维码关注公众号,回复: 10419927 查看本文章
select employee_id,last_name,job_id,salary
from employees
where salary < ALL(
select salary from employees where job_id ='IT_PROG')

4.3.子查询中的空值问题

SELECT emp.last_name
FROM   employees emp
WHERE  emp.employee_id NOT IN
                             (SELECT mgr.manager_id
                              FROM   employees mgr);
--no rows selected

当主查询中匹配条件中有空值时 如果子查询中也返回的有空值 空值也是可以匹配的

四、分页查询

数据伪列:指的是表中不存在但却有可以直接使用的列,在oracle中除了SYSDATE外还存着有ROWNUMROWID连个与行记录有关的伪列
虚拟表 dual 可以用来测试函数或一般的运算

1.ROWNUM

行号:ROWNUM 查询数据时,可以使用ROWNUM这个伪列,动态的生成行记录的编号。
ROWNUM不是固定的,而是动态生成的。

--rownum 是一个数据伪列 不存在  但可以直接使用的列
--rownum 自动生成  与数据无关 在每次的查询中总是从1开始
--显示前20行记录
select rownum  ,employee_id,first_name ,last_name from employees where rownum <= 20 ;

分页查询

--显示11 - 20 条记录  现在每页显示10记 录  显示第二页 11 -20
select * from (
select rownum r ,employee_id,first_name ,last_name from employees where rownum <= 20 ) temp
where temp.r >10;
--显示11 - 20 条记录  现在每页显示10记 录  显示第二页 11 -20
select * from (
select rownum r ,employee_id,first_name ,last_name from employees where rownum <= 30 ) temp
where temp.r >20;
总记录数:total = 107 查出来的
每页显示的条数:pageSize= 10 这个一般是固定的,但是也可以改变
总页数:page = 107/10+1 = 11 计算出来的
当前页数:currentPage  有用户决定的

分页的语法:

select * from (
select rownum r ,employee_id,first_name ,last_name from employees where rownum <= '结束的rounum' ) temp
where temp.r >‘开始的rownum’;
结束的rounum = currentPage(1) *10;
开始的rownum=(currentPage - 1) * 10
select * from (
select rownum r ,employee_id,first_name ,last_name from employees where rownum <= '结束的rounum' ) temp
where temp.r >=‘开始的rownum’;
结束的rounum = currentPage(1) *10;
开始的rownum=(currentPage - 1) * 10 + 1
mysql的分页:limit 当前开始的记录数  每页显示的条数
sqlserver:top

2.ROWID

对查询的结果进行更新

SELECT * FROM employees for update;
--rowid 为每一条记录生成一个唯一的行标识  18位的16进制数
select rowid ,employee_id,first_name ,last_name from employees;
--列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称,上级的姓名
select e.employee_id ,e.last_name, e.hire_date ,d .department_name,m.last_name,m.hire_date
from employees e,departments d,employees m
where e.department_id = d.department_id and e.manager_id = m.employee_id
and  e.hire_date < m.hire_date;

随堂练习

添加链接描述

发布了67 篇原创文章 · 获赞 6 · 访问量 1930

猜你喜欢

转载自blog.csdn.net/weixin_45801537/article/details/104270656