赞
踩
SQL 中子查询的使用大大增强了 SELECT 查询的能力,因为很多时候查询需要从结果集中获取数据,或者 需要从同一个表中先计算得出一个数据结果,然后与这个数据结果(可能是某个标量,也可能是某个集 合)进行比较。
求员工表中工资比 Abel这个员工工资高的其他员工
1、分步骤查询
- SELECT salary FROM employees WHERE last_name = 'Abel';
-
-
- SELECT last_name,salary FROM employees WHERE salary > 11000;
2、自连接
SELECT e2.last_name,e2.salary FROM employees e1,employees e2 WHERE e1.last_name = 'Abel' AND e1.`salary` < e2.`salary`
3、子查询
SELECT salary FROM employees WHERE salary > ( SELECT salary FROM employees WHERE last_name = 'Abel' );
子查询的基本语法结构:
我们按内查询的结果返回一条还是多条记录,将子查询分为 单行子查询 、 多行子查询
我们按内查询是否被执行多次,将子查询划分为 相关(或关联)子查询 和 不相关(或非关联)子查询 ;
单行比较操作符
查询工资大于 149 号员工工资的员工的信息
返回 job_id 与 141 号员工相同, salary 比 143 号员工多的员工姓名, job_id 和工资
返回公司工资最少的员工的 last_name,job_id 和 salary
查询与 141 号或 174 号员工的 manager_id 和 department_id 相同的其他员工 employee_id ,manager_id , department_id
- SELECT employee_id, manager_id, department_id
- FROM employees
- WHERE manager_id IN
- (SELECT manager_id FROM employees WHERE employee_id IN (174,141))
-
- AND department_id IN
- (SELECT department_id FROM employees WHERE employee_id IN (174,141))
-
- AND employee_id NOT IN(174,141)
- 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);
查询最低工资大于 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
- );
在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;
返回其它job_id中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id以及salary
查询平均工资最低的部门id
方式1:
- SELECT
- department_id
- FROM
- employees
- GROUP BY
- department_id
- HAVING
- AVG(salary) = (
- SELECT
- MIN(avg_sal)
- FROM
- (
- SELECT
- AVG(salary) avg_sal
- FROM
- employees
- GROUP BY
- department_id
- ) dept_avg_sal
- )
方式2:
- SELECT
- department_id
- FROM
- employees
- GROUP BY
- department_id
- HAVING
- AVG(salary) <= ALL (
- SELECT
- AVG(salary) avg_sal
- FROM
- employees
- GROUP BY
- department_id
- )
关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称之为 关联子查询 。 相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询
语法结构:
查询员工中工资大于本部门平均工资的员工的 last_name,salary 和其 department_id
方式1:相关子查询
方式2:在 FROM 中使用子查询
- SELECT
- last_name,
- salary,
- e1.department_id
- FROM
- employees e1,
- (
- SELECT
- department_id,
- AVG(salary) dept_avg_sal
- FROM
- employees
- GROUP BY
- department_id
- ) e2
- WHERE
- e1.`department_id` = e2.department_id
- AND e2.dept_avg_sal < e1.`salary`;
查询员工的id,salary,按照department_name 排序
- SELECT
- employee_id,
- salary
- FROM
- employees e
- ORDER BY
- (
- SELECT
- department_name
- FROM
- departments d
- WHERE
- e.`department_id` = d.`department_id`
- );
若 employees 表中 employee_id 与 job_history 表中 employee_id 相同的数目不小于 2 ,输这些相同 id 的员工的 employee_id,last_name 和其 job_id
- SELECT
- e.employee_id,
- last_name,
- e.job_id
- FROM
- employees e
- WHERE
- 2 <= (
- SELECT
- COUNT(*)
- FROM
- job_history
- WHERE
- employee_id = e.employee_id
- );
查询公司管理者的 employee_id , last_name , job_id , department_id 信息
方式1:
- SELECT
- employee_id,
- last_name,
- job_id,
- department_id
- FROM
- employees e1
- WHERE
- EXISTS (
- SELECT
- *
- FROM
- employees e2
- WHERE
- e2.manager_id = e1.employee_id
- );
方式2:自连接
- SELECT DISTINCT
- e1.employee_id,
- e1.last_name,
- e1.job_id,
- e1.department_id
- FROM
- employees e1
- JOIN employees e2
- WHERE
- e1.employee_id = e2.manager_id;
方式3:
- SELECT DISTINCT
- e1.employee_id,
- e1.last_name,
- e1.job_id,
- e1.department_id
- FROM
- employees e1
- WHERE
- e1.employee_id IN (
- SELECT DISTINCT
- manager_id
- FROM
- employees
- );
查询departments表中,不存在于employees表中的部门的department_iddepartment_name
- SELECT
- department_id,
- department_name
- FROM
- departments d
- WHERE
- NOT EXISTS (
- SELECT
- 'X'
- FROM
- employees
- WHERE
- department_id = d.department_id
- );
- UPDATE table1 alias1
- SET COLUMN = (
- SELECT
- expression
- FROM
- table2 alias2
- WHERE
- alias1. COLUMN = alias2. COLUMN
- );
在 employees 中增加一个 department_name 字段,数据为员工对应的部门名称
方式1:
- ALTER TABLE employees ADD (
- department_name VARCHAR2 (14)
- );
方式2:
- UPDATE employees e
- SET department_name = (
- SELECT
- department_name
- FROM
- departments d
- WHERE
- e.department_id = d.department_id
- );
- DELETE
- FROM
- table1 alias1
- WHERE
- COLUMN operator (
- SELECT
- expression
- FROM
- table2 alias2
- WHERE
- alias1. COLUMN = alias2. COLUMN
- );
删除表 employees 中,其与 emp_history 表皆有的数据
- DELETE
- FROM
- employees e
- WHERE
- employee_id IN (
- SELECT
- employee_id
- FROM
- emp_history
- WHERE
- employee_id = e.employee_id
- );
谁的工资比 Abel 的高?
方式1:自连接
- SELECT
- e2.last_name,
- e2.salary
- FROM
- employees e1,
- employees e2
- WHERE
- e1.last_name = 'Abel'
- AND e1.`salary` < e2.`salary`
方式2:子查询
- SELECT
- last_name,
- salary
- FROM
- employees
- WHERE
- salary > (
- SELECT
- salary
- FROM
- employees
- WHERE
- last_name = 'Abel'
- );
以上两种方式有好坏之分吗? 解答: 自连接方式好!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。