SELECT last_name, job_id, salary FROM eployees WHERE job_id = ( SELECT job_id FROM eployees WHERE employee_id = 141 ) AND salary > ( SELECT salary FROM eployees WHERE employee_id = 143 );
题目:返回公司工资最少的员工的last_name,job_id和salary
1 2 3 4 5
SELECT last_name, job_id, salary FROM employees WHERE salary = (SELECT MIN(salary) FROM employees);
# 实现方式一:不成对比较 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);
3) HAVING中的子查询
首先执行子查询。 向主查询中的HAVING 子句返回结果。
题目:查询最低工资大于50号部门最低工资的部门id和其最低工资
1 2 3 4 5 6 7
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;
5) 子查询中的空值问题
1 2 3 4 5 6
SELECT last_name, job_id FROM employees WHERE job_id = (SELECT job_id FROM employees WHERE last_name = 'Haas');
子查询不返回任何行
6) 非法使用子查询
1 2 3 4 5 6
SELECT employee_id, last_name FROM employees WHERE salary = (SELECT MIN(salary) FROM employees GROUP BY department_id);
SELECT employee_id, last_name, job_id, salary FROM employees WHERE job_id <> 'IT_PROG' AND salary < ANY( SELECT salary FROM emplyees WHERE job_id = 'IT_PROG' );
题目:查询平均工资最低的部门id
1 2 3 4 5 6 7 8 9 10 11 12
#方式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 );
1 2 3 4 5 6 7 8 9
#方式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 );
3) 空值问题
1 2 3 4 5 6 7
SELECT last_name FROM employees WHERE employee_id NOT IN ( SELECT manager_id FROM employees WHERE manager_id IS NOT NULL );
# 方式一:使用相关子查询 SELECT last_name, salary, department FROM employees e1 WHERE salary > ( SELECT AVG(salary) FROM employees e2 WHERE department_id = e1.`department_id` ); # 方式二:在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) t_dept_avg_salary WHERE e.department_id = t_dept_avg_salary.department_id AND e.salary > t_dept_avg_salary.avg_sal;
# 方式一: SELECT d.department_id, d.department_name FROM departments e RIGHT JOIN departments d ON e.`department_id` = d.`department_id` WHERE e.`department_id` IS NULL;
# 方式二: SELECT department_id, department_name FROM departments d WHERE NOT EXISTS ( SELECT * FROM employees e WHERE d.`department_id` = e.`department_id` );
4) 相关更新
1 2 3 4
UPDATE table1 alias1 SET column = (SELECT expression FROM table2 alias2 WHERE alias1.column = alias2.column);
使用相关子查询依据一个表中的数据更新另一个表的数据。
题目:在employees中增加一个department_name字段,数据为员工对应的部门名称
1 2 3 4 5 6 7 8 9
# 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);
5) 相关删除
1 2 3 4
DELETE FROM table1 alias1 WHERE column operator (SELECT expression FROM table2 alias2 WHERE alias1.column = alias2.column);
使用相关子查询依据一个表中的数据删除另一个表的数据。
题目:删除表employees中,其与emp_history表皆有的数据
1 2 3 4 5 6
DELETE FROM employees e WHERE employee_id in( SELECT employee_id FROM emp_history WHERE employee_id = e.employee_id );
5. 思考题
问题:谁的工资比Abel的高? 解答:
1 2 3 4 5
#方式1:自连接 SELECT e2.last_name,e2.salary FROM employees e1,employees e2 WHERE e1.last_name = 'Abel' AND e1.`salary` < e2.`salary`;
1 2 3 4 5 6 7 8
#方式2:子查询 SELECT last_name,salary FROM employees WHERE salary > ( SELECT salary FROM employees WHERE last_name = 'Abel' );
# 方式一 SELECT * FROM departments WHERE department_id = ( 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 ) t_dept_avg_sal ) );
# 方式二 SELECT * FROM departments WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING AVG(salary) <= ALL ( SELECT AVG(salary) avg_sal FROM employees GROUP BY department_id ) );
# 方式三: LIMIT SELECT * FROM departments WHERE department_id IN ( SELECT department_id FROM employees GROUP BY department_id HAVING AVG(salary) = ( SELECT AVG(salary) avg_sal FROM employees GROUP BY department_id ORDER BY avg_sal ASC LIMIT 1 ) );
# 方式四 SELECT d.* FROM departments d, ( SELECT department_id, AVG(salary) avg_sal FROM employees GROUP BY department_id ORDER BY avg_sal ASC LIMIT 0,1 ) t_dept_avg_sal WHERE d.`department_id` = t_dept_avg_sal.`department_id`;
查询平均工资最低的部门信息和该部门的平均工资 (相关子查询)
1 2 3 4 5 6 7 8 9
SELECT d.*, (SELECT AVG(salary) FROM employees WHERE department_id = d.`department_id`) avg_sal FROM departments d, ( SELECT department_id, AVG(salary) avg_sal FROM employees GROUP BY department_id ORDER BY avg_sal ASC LIMIT 0,1 ) t_dept_avg_sal WHERE d.`department_id` = t_dept_avg_sal.`department_id`;
查询平均工资最高的job信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
SELECT * FROM jobs WHERE job_id = ( SELECT job_id FROM employees GROUP BY job_id HAVING AVG(salary) = ( SELECT MAX(avg_sal) FROM ( SELECT AVG(salary) avg_sal FROM employees GROUP BY job_id ) t_job_avg_sal ) );
查询平均工资高于公司平均工资的部门有哪些?
1 2 3 4 5 6 7 8
SELECT depatment_id FROM employees WHERE department_id IS NOT NULL GROUP BY department_id HAVING AVG(salary) > ( SELECT AVG(salary) FROM eployees );
# 方式一: SELECT MIN(salary) FROM employees WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING MAX(salary) = ( SELECT MIN(max_sal) FROM ( SELECT MAX(salary) max_sal FROM employees GROUP BY department_id ) t_dept_max_sal ) );
# 方式二: SELECT MIN(salary) FROM employees WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING MAX(salary) <= ALL ( SELECT MAX(salary) FROM employees GROUP BY department_id ) );
# 方式三: SELECT MIN(salary) FROM employees WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING MAX(salary) = ( SELECT MAX(salary) max_sal FROM employees GROUP BY department_id ORDER BY max_sal ASC LIMIT 0,1 ) );
# 方式四: FROM employees e, ( SELECT department_id, MAX(salary) max_sal FROM employees GROUP BY department_id ORDER BY max_sal ASC LIMIT 0,1 ) t_dept_max_sal WHERE e.`department_id` = t_dept_max_sal.`department_id`;
SELECT last_name, department_id, email, salary FROM employees WHERE employee_id IN ( SELECT DISTINCT manager_id FROM employees WHERE department_id = ( SELECT department_id FROM employees GROUP BY department_id HAVING AVG(salary) = ( SELECT MAX(avg_sal) FROM ( SELECT AVG(salary) avg_sal FROM employees GROUP BY department_id ) t_dept_avg_sal ) ) );
SELECT last_name, department_id, email, salary FROM employees WHERE employee_id IN ( SELECT DISTINCT manager_id FROM employees e, ( SELECT department_id, AVG(salary) avg_sal FROM employees GROUP BY department_id ORDER BY avg_sal DESC LIMIT 0,1 ) t_dept_avg_sal WHERE e.`department_id` = t_dept_avg_sal.`department_id` );
查询部门的部门号,其中不包括job_id是”ST_CLERK”的部门号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
SELECT department_id FROM departments WHERE department_id NOT IN ( SELECT DISTINCT department_id FROM employees WHERE job_id = `ST_CLERK` );
SELECT department_id FROM department d WHERE NOT EXISTS ( SELECT * FROM employees e WHERE d.`department_id` = e.`department_id` AND e.`job_id` = 'ST_CLERK' );
选择所有没有管理者的员工的last_name
1 2 3 4 5 6 7
SELECT last_name FROM employees emp WHERE NOT EXISTS ( SELECT * FROM employees mgr WHERE emp.`manager_id` = mgr.`employee_id` );
查询员工号、姓名、雇用时间、工资,其中员工的管理者为 ‘De Haan’
1 2 3 4 5 6 7
SELECT employee_id, last_name, hire_date, salary FROM employee WHERE manager_id IN ( SELECT manager_id FROM employee WHERE last_name = 'De Haan' );
查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资(相关子查询)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
SELECT department_id, last_name, salary FROM employees e1 WHERE salary > ( SELECT AVG(salary) FROM employees e2 WHERE e2.`department_id` = e1.`department_id` );
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 ) t_dept_avg_sal WHERE e.`department_id` = t_dept_avg_sal.`department_id` AND e.`salary` > t_dept_avg_sal.`avg_sal`;
查询每个部门下的部门人数大于5的部门名称(相关子查询)
1 2 3 4 5 6 7
SELECT department_name FROM departments d WHERE 5 < ( SELECT COUNT(*) FROM employees e WHERE d.`department_id` = e.`department_id` );
查询每个国家下的部门个数大于2的国家编号(相关子查询)
1 2 3 4 5 6 7
SELECT country_id FROM locations l WHERE 2 < ( SELECT COUNT(*) FROM department d WHERE l.`location_id` = d.`location_id` );