方式一:
SELECT salary
FROM employees
WHERE last_name='Abel';
SELECT last_name
FROM employees
WHERE salary>11000;
方式二:自连接
SELECT last_name,salary
FROM employees e1,employees e2
WHERE e2.salary>e1.salary #多表的连接条件
AND e1.last_name='Abel';
方式三:子查询
SELECT last_name,salary
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name='Abel'
);
注意:
子查询(内查询)在主查询之前一次执行完成
子查询的结果被主查询(外查询)使用
子查询要包括在括号内
将子查询放在比较条件的右侧
单行操作符对应单行子查询,多行操作符对应子查询
角度1:从内查询返回的结果的条目数
单行子查询(结果一个) vs 多行子查询(结果多条)
角度2:内查询是否被执行多次
相关子查询vs不相关子查询
子查询的编写技巧:
1.从里往外写
2.从外往里写
SELECT last_name
FROM employees
WHERE salary(
SELECT salary
FROM employees
WHERE employee_id=149
);
SELECT last_name,job_id,salary
FROM employees
WHERE job_id>(
SELECT job_id
FROM employees
WHERE emplyee_id=141)
AND salary>(
SELECT salary
FROM employees
WHERE employee_id=143
);
SELECT last_name,job_id,salary
FROM employees
WHERE salary(
SELECT MIN(salary)
FROM employees
);
方式1:
SELECT employee_id,manager_id,department_id
FROM employees
WHERE manager_id=(
SELECT manager_id
FROM employees
WHERE employee_id =141)
AND department_id=(
SELECT department_id
FROM employees
WHERE employee_id =141
)
AND employee_id <> 141;
方式2:了解
SELECT employee_id,manager_id,department_id
FROM employees
WHERE (manager_id,department_id)=(
SELECT manager_id,department_id
FROM employees
WHERE employee_id=141
);
SELECT department_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) >(
SELECT MIN(salary)
FROM employees
WHERE department_id=50
);
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;
SELECT last_name
FROM employees
WHERE job_id=(
SELECT job_id
FROM employees
WHERE last_name='sas'
);
| 操作符 | 意义 |
|---|---|
| IN | 等于列表中的任意一个 |
| ANY | 需要和单行比较操作符一起使用,和子查询返回的某一个值比较 |
| ALL | 需要和单行比较操作符一起使用,和子查询返回的所有值比较 |
| SOME | 实际上是ANY的别名,作用相同,一般常用ANY |
SELECT employee_id,last_name,job_id,salar
FROM employees
WHERE job_id<> 'IT_PROG'
AND salary <ANY(
SELECT salary
FROM employees
WHERE job_id='IT_PROG'
);
SELECT employee_id,last_name,job_id,salar
FROM employees
WHERE job_id<> 'IT_PROG'
AND salary <ALL(
SELECT salary
FROM employees
WHERE job_id='IT_PROG'
);
方式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
);
子查询中含有NULL,外查询不返回行
关联子查询:每执行一次外部查询,子查询都要重新计算一次。
SELECT last_name,salary,department_id
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
);
方式1:相关子查询
SELECT last_name,salary,department_id
FROM employees e1
WHERE salary>(
SELECT AVG(salary)
FROM employees e2
WHERE department_id=e1.department_id
);
方式2:在FROM中声明子查询
SELECT e.last_name,e.salary.e.department_id
FROM employees e,(SELECT department_id,AVG(salary) avg_sal
FROM employees
GROUP BY department_id) dept_avg_sal
WHERE e.`department_id`=dept_avg_sal.`department_id`
AND e.salary>dept_avg_sal.`avg_sal`;
-ORDER BY
题目:在查询员工的id、salary,按照department_name进行排序
SELECT employee_id,salary
FROM emplyees e
ORDER BY(
SELECT department_name
FROM departments d
WHERE e.`department_id`=d.`department_id`
);
结论:在SELECT 中,除了GROUP BY 和LIMIT,其他都可以声明子查询
SELECT *
FROM job_history;
SELECT employee_id,last_name,job_id
FROM employees e
WHERE 2<=(
SELECT COUNT(*)
FROM job_history j
WHERE e.`employee_id`=j.`employee_id`
);
如果在子查询中不存在满足的条件的行:
条件返回FALSE
继续在子查询中查找
如果在子查询中存在 满足条件的行:
不在子查询中继续查找
条件返回TRUE
子查询:
SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE employee_id IN(
SELECT DISYINCT manager_id
FROM employees
);
使用EXISTS
SELECT employee_id,last_name,job_id,department_id
FROM employees e1
WHERE EXISTS(
SELECT *
FROM employees e2
WHERE e1.`employee_id`=e2.`manager_id`
);
SELECT department_id,department_name
FROM departments d
WHERE EXISTS (
SELECT *00
FROM employees e
WHERE d.`department_id`=e.`department_id`
);