oracle子查询

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/czh500/article/details/82796106
--
SELECT emp.last_name, emp.salary,  emp.email, first_name
FROM employees emp
WHERE emp.salary > 3000

/*

子查询

顺便说一下,软件开发要具备一个想法或思想:大处着眼,小处着手

*/

--

/*

单行子查询
1.只返回一行
2.使用单行比较操作符
=
>
>=
<
<=
<>或者用!=

*/

--谁的工资比abel高
SELECT EMP.SALARY, EMP.*
  FROM EMPLOYEES EMP
 WHERE EMP.SALARY > (SELECT EMP.SALARY
                       FROM EMPLOYEES EMP
                      WHERE LOWER(EMP.LAST_NAME) = 'abel')

--查询员工Chen的manager信息
  SELECT EMP.EMPLOYEE_ID, EMP.LAST_NAME, EMP.SALARY
          FROM EMPLOYEES EMP
         WHERE EMP.EMPLOYEE_ID =
               (SELECT EMP.MANAGER_ID
                  FROM EMPLOYEES EMP
                 WHERE LOWER(EMP.LAST_NAME) = 'chen')
        
        --返回job_id与141号员工相同,salary比143员工多的员工姓名,job_id和工资
        SELECT EMP.LAST_NAME, EMP.JOB_ID, EMP.SALARY
          FROM EMPLOYEES EMP
         WHERE EMP.JOB_ID = (SELECT EMP.JOB_ID
                               FROM EMPLOYEES EMP
                              WHERE EMP.EMPLOYEE_ID = 141)
           AND EMP.SALARY > (SELECT EMP.SALARY
                               FROM EMPLOYEES EMP
                              WHERE EMP.EMPLOYEE_ID = 143)
                
                --返回公司工资最少的员工的last_name, JOB_ID和SALARY
                SELECT EMP.LAST_NAME, EMP.JOB_ID, EMP.SALARY
                  FROM EMPLOYEES EMP
                 WHERE EMP.SALARY =
                       (SELECT MIN(EMP.SALARY) FROM EMPLOYEES EMP)
                        --查询最低工资大于50号部门最低工资的部门id和其最低工资
                        SELECT EMP.DEPARTMENT_ID, MIN(EMP.SALARY)
                          FROM EMPLOYEES EMP
                        HAVING MIN(EMP.SALARY) > (SELECT MIN(EMP.SALARY)
                                                    FROM EMPLOYEES EMP
                                                   WHERE EMP.DEPARTMENT_ID = 50)
                         GROUP BY EMP.DEPARTMENT_ID
--
SELECT EMP.DEPARTMENT_ID, MIN(EMP.SALARY)
                          FROM EMPLOYEES EMP
                          GROUP BY emp.department_id
                        HAVING MIN(EMP.SALARY) > (SELECT MIN(EMP.SALARY)
                                                    FROM EMPLOYEES EMP
                                                   WHERE EMP.DEPARTMENT_ID = 50)
--
SELECT EMP.DEPARTMENT_ID, MIN(EMP.SALARY)
                          FROM EMPLOYEES EMP
                          GROUP BY emp.department_id
                        HAVING MIN(EMP.SALARY) > (SELECT MIN(EMP.SALARY)
                                                    FROM EMPLOYEES EMP
                                                   WHERE EMP.DEPARTMENT_ID = 50)
                                                   ORDER BY EMP.DEPARTMENT_ID ASC
/*

多行子查询
1.返回多行
2.使用多行比较操作符
in 等于列表中的任意一个
any 和子查询返回的某一个值比较
all 和子查询返回的所有值比较

*/                                                   
--
/*

返回其他部门中比job_id为'IT_PROG'部门任一工资低的员工的员工号、姓名、job_id以及salary
下面演示any和all

*/
--使用ANY的方式
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG' 
AND emp.salary < 
ANY(
SELECT emp.salary 
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
) 
ORDER BY emp.employee_id ASC
--也可以改成下面这种方式,效果是一样的
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG' 
AND emp.salary < (
SELECT MAX(emp.salary)
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
)
ORDER BY emp.employee_id ASC

/*

返回其他部门中比job_id为'IT_PROG'部门任意(所有)工资低的员工的员工号、姓名、job_id以及salary

*/

--使用ALL的方式
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG' 
AND emp.salary < 
ALL(
SELECT emp.salary 
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
) 
ORDER BY emp.employee_id ASC
--也可以改成下面这种方式,效果是一样的
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG' 
AND emp.salary < (
SELECT MIN(emp.salary)
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
)
ORDER BY emp.employee_id ASC

/*

子查询中的空值问题

*/
--子查询中查到了结果
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id = (
SELECT emp.manager_id
FROM employees emp
WHERE emp.employee_id = 117
)
/*

子查询中没有查到符合条件的数据,所以返回空值给外层查询,所以外层查询自然就查不到任何的数据,
子查询中的空值问题不会报错,只是没有查询结果而已

*/
--子查询中没有查到结果
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id = (
SELECT emp.manager_id
FROM employees emp
WHERE emp.employee_id = 666
)
--
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id NOT IN (
SELECT emp.manager_id
FROM employees emp
)
--
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id IN (
SELECT emp.manager_id
FROM employees emp
)

--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id IS NULL
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id IN (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id NOT IN (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id != (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id != (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id != NULL
--
SELECT NULL, NULL AS "空空如也", 'abc123', 'hello', '江西赣州于都县' AS "家乡", '深圳' "工作地", emp.last_name, emp.salary
FROM employees emp
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id IN (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = ANY (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = ALL (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)

/*
子查询练习题
*/
--查询工资最低的员工的信息,last_name, salary
SELECT emp.last_name, emp.salary
FROM employees emp
WHERE emp.salary = (
SELECT MIN(emp.salary)
FROM employees emp
)
--查询平均工资最低的部门信息
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MIN(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id

--查询平均工资最低的部门信息
SELECT dep.department_id 部门编号, dep.department_name AS "部门名称", dep.*
FROM departments dep
WHERE dep.department_id = (
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MIN(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
--查询平均工资最低的部门信息和该部门的平均工资(此题目有点难度)
SELECT dep.department_id 部门编号, dep.department_name AS "部门名称", dep.*, 
--(SELECT AVG(emp.salary) AS "平均薪水"
(SELECT AVG(emp.salary)
FROM employees emp
WHERE emp.department_id = dep.department_id) AS "平均工资"
FROM departments dep
WHERE dep.department_id = (
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MIN(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)

--查询平均工资最高的job的信息(万一有多个job_id的平均工资等于最高平均工资,那就不能用=等号了,应该改成in)
SELECT job.*
FROM jobs job
WHERE job.job_id = (
SELECT  
emp.job_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT  
MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.job_id
)
GROUP BY emp.job_id
)

--把=等号改成in
SELECT job.*
FROM jobs job
--这里改成in
WHERE job.job_id in (
SELECT  
emp.job_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT  
MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.job_id
)
GROUP BY emp.job_id
)

--查询平均工资高于公司平均工资的部门有哪些?
SELECT dep.*, (SELECT AVG(emp.salary) FROM employees emp WHERE emp.department_id = dep.department_id )
FROM departments dep
WHERE dep.department_id IN (
SELECT emp.department_id
--, AVG(emp.salary) 
FROM employees emp
GROUP BY emp.department_id
HAVING AVG(emp.salary) > (
SELECT AVG(emp.salary)
FROM employees emp
)
)
--
SELECT emp.department_id, AVG(emp.salary) AS avg_salary
FROM employees emp
GROUP BY emp.department_id
HAVING AVG(emp.salary) > (
SELECT AVG(emp.salary)
FROM employees emp
)
ORDER BY avg_salary DESC
--

--查询公司中所有manager的详细信息
SELECT emp.*
FROM employees emp 
WHERE emp.employee_id IN (
SELECT emp.manager_id 
FROM employees emp
WHERE emp.manager_id IS NOT NULL
GROUP BY emp.manager_id
)
--另一种写法
SELECT emp.*
FROM employees emp 
WHERE emp.employee_id IN (
SELECT emp.manager_id 
FROM employees emp
)



--各个部门中 最高工资中最低的那个部门的 最低工资是多少?
SELECT emp.department_id, MAX(emp.salary)
FROM employees emp
GROUP BY emp.department_id
ORDER BY MAX(emp.salary) ASC
--
SELECT MIN(MAX(emp.salary))
FROM employees emp
GROUP BY emp.department_id
--
SELECT emp.department_id, MAX(emp.salary), MIN(emp.salary)
FROM employees emp
HAVING MAX(emp.salary) = (
SELECT MIN(MAX(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
--
SELECT MIN(emp.salary)
FROM employees emp
WHERE emp.department_id IN (
--WHERE emp.department_id = (
SELECT emp.department_id
FROM employees emp
HAVING MAX(emp.salary) = (
SELECT MIN(MAX(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
--
SELECT * FROM employees emp WHERE emp.department_id = 10
--
SELECT MIN(emp.salary)
FROM employees emp
WHERE emp.department_id IN (40, 60, 80)
--
SELECT emp.department_id, MAX(emp.salary)
FROM employees emp
GROUP BY emp.department_id
HAVING MAX(emp.salary) = 24000 OR MAX(emp.salary) = 14000




--查询平均工资最高的部门的manager的详细信息:last_name, department_id, email,salary
SELECT emp.department_id, AVG(emp.salary) AS avg_salary
FROM employees emp
GROUP BY emp.department_id
ORDER BY avg_salary DESC
--
SELECT MAX(AVG(emp.salary)) AS MAX_avg_salary
FROM employees emp
GROUP BY emp.department_id
--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
--
SELECT emp.*
FROM employees emp
WHERE emp.department_id IN(
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
--
SELECT last_name AS 名字, department_id AS "部门编号", email 邮箱, salary 薪水, emp.*
FROM employees emp
WHERE emp.employee_id IN (
SELECT emp.manager_id
FROM employees emp
WHERE emp.department_id IN(
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
)


--查询1999年来公司的员工中的最高工资的那个员工的信息
SELECT emp.salary, emp.*
FROM employees emp
WHERE to_char(emp.hire_date, 'yyyy') = '1999'
ORDER BY emp.salary DESC
--
SELECT MAX(emp.salary)
FROM employees emp
WHERE to_char(emp.hire_date, 'yyyy') = '1999'
--
SELECT emp.salary, emp.*
FROM employees emp
WHERE emp.salary IN (
--WHERE emp.salary = (
SELECT MAX(emp.salary)
FROM employees emp
WHERE to_char(emp.hire_date, 'yyyy') = '1999'
)
AND to_char(emp.hire_date, 'yyyy') = '1999'

--1.查询和Zlotkey相同部门的员工姓名和雇用日期
SELECT emp.last_name AS 员工姓名, emp.hire_date "雇用日期", emp.*
FROM employees emp
--可以把=等号改成in
WHERE emp.department_id = (
SELECT emp.department_id
FROM employees emp 
WHERE lower(emp.last_name) = 'zlotkey'
)
--也可以把!=符号改成<>
AND lower(emp.last_name) != 'zlotkey'

--2.查询工资比公司平均工资高的员工的员工号,姓名和工资
SELECT emp.employee_id, emp.last_name, emp.salary
FROM employees emp
WHERE emp.salary > (
SELECT AVG(emp.salary)
FROM employees emp
)

--3.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(这道题目有点难度)
--各个部门的平均工资
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
GROUP BY emp.department_id
--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
WHERE emp.department_id = emp.department_id
GROUP BY emp.department_id
--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
WHERE 20 = 20
GROUP BY emp.department_id
--正确答案
SELECT emp1.employee_id, emp1.last_name, emp1.salary
FROM employees emp1
WHERE emp1.salary > (
SELECT AVG(emp2.salary)
FROM employees emp2
WHERE emp1.department_id = emp2.department_id
GROUP BY emp2.department_id
)
--


--4.查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名
SELECT emp.employee_id, emp.last_name, emp.*
FROM employees emp
WHERE emp.department_id IN (
SELECT emp.department_id
FROM employees emp
--WHERE emp.last_name LIKE '%' || lower('U') || '%'
WHERE emp.last_name LIKE '%u%'
)
AND emp.last_name NOT LIKE '%u%'


--
SELECT *
FROM employees emp
WHERE last_name = 'Pataballa'
--
SELECT *
FROM employees emp
WHERE last_name = 'Pata' || 'balla'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%Pata' || 'bal%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%Patabal%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%' || 'Pata' || 'bal' || '%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%' || upper('p') || 'ata' || 'bal' || '%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%' || lower('P') || 'ata' || 'bal' || '%'

--5.查询在部门的location_id为1700的部门工作的员工的员工号
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.department_id IN (
SELECT dep.department_id
FROM departments dep
WHERE dep.location_id = 1700
)

--6.查询管理者是King的员工姓名和工资
SELECT emp.last_name AS "员工姓名", emp.salary 薪水, emp.*
FROM employees emp
WHERE emp.manager_id IN(
SELECT emp.employee_id
FROM employees emp
WHERE LOWER(emp.last_name) = 'king'
)


--
SELECT emp.job_id, AVG(emp.salary) AS sal
FROM employees emp 
GROUP BY emp.job_id
ORDER BY sal DESC
--
SELECT emp.department_id, AVG(emp.salary) AS sal
FROM employees emp 
GROUP BY emp.department_id
ORDER BY sal DESC

--
SELECT emp.job_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) >= 17000 --HAVING关键字也可以放在FROM后面,也可以放在GROUP BY后面
GROUP BY emp.job_id
--HAVING AVG(emp.salary) >= 17000

--
--SELECT MAX(emp.salary)
SELECT AVG(emp.salary), MAX(emp.salary)
--SELECT AVG(emp.salary)
--SELECT emp.salary
FROM employees emp
--HAVING AVG(emp.salary) >= 6400 AND MAX(emp.salary) > 23000
--HAVING AVG(emp.salary) >=  6400
--HAVING AVG(emp.salary) >=  6400
HAVING MAX(emp.salary) > 23000

--
SELECT emp.department_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
GROUP BY emp.department_id
HAVING AVG(emp.salary) > 9000

--
SELECT emp.salary
FROM employees emp
WHERE emp.salary > 6400

--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
--HAVING emp.salary > 6400
HAVING AVG(emp.salary) > 6400 AND department_id > 80
GROUP BY emp.department_id

--以下这种写法是错误的
SELECT emp.last_name, emp.salary, emp.employee_id
FROM employees emp
HAVING AVG(emp.salary) > 6400

--
SELECT MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300
--
SELECT AVG(emp.salary)
FROM employees emp
HAVING MAX(emp.salary) > 23500
--
SELECT AVG(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300
--
SELECT AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300
--
SELECT AVG(emp.salary), MAX(emp.salary), SUM(emp.salary), MIN(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300

--
--SELECT emp.department_id
SELECT emp.department_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6400
GROUP BY emp.department_id
--
SELECT emp.department_id
--SELECT emp.department_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6400
GROUP BY emp.department_id

--
SELECT emp.department_id, emp.job_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
--HAVING AVG(emp.salary) > 6400 
/*
还有一个要注意:HAVING关键字的作用也是过滤数据,HAVING后面可以跟组函数,如
果HAVING要过滤某个字段的话,只能过滤SELECT后面出现了的字段,比
如这里的SELECT emp.department_id, emp.job_id, AVG(emp.salary), MAX(emp.salary)这句话,SELECT后面出
现了department_id和job_id这2个字段,所以HAVING后面只能跟组函数以及department_id和job_id这2个字段
*/
--不等于可以使用<>符号,也可以使用!=符号,如下:
HAVING emp.department_id IN (40, 60, 80, 100) AND (emp.job_id != 'IT' OR emp.job_id <> 'IT')
GROUP BY emp.department_id, emp.job_id

--
SELECT emp.last_name, emp.salary,  emp.email, first_name
FROM employees emp
WHERE emp.salary > 3000

/*

子查询

顺便说一下,软件开发要具备一个想法或思想:大处着眼,小处着手

*/

--

/*

单行子查询
1.只返回一行
2.使用单行比较操作符
=
>
>=
<
<=
<>或者用!=

*/

--谁的工资比abel高
SELECT EMP.SALARY, EMP.*
  FROM EMPLOYEES EMP
 WHERE EMP.SALARY > (SELECT EMP.SALARY
                       FROM EMPLOYEES EMP
                      WHERE LOWER(EMP.LAST_NAME) = 'abel')

--查询员工Chen的manager信息
  SELECT EMP.EMPLOYEE_ID, EMP.LAST_NAME, EMP.SALARY
          FROM EMPLOYEES EMP
         WHERE EMP.EMPLOYEE_ID =
               (SELECT EMP.MANAGER_ID
                  FROM EMPLOYEES EMP
                 WHERE LOWER(EMP.LAST_NAME) = 'chen')
        
        --返回job_id与141号员工相同,salary比143员工多的员工姓名,job_id和工资
        SELECT EMP.LAST_NAME, EMP.JOB_ID, EMP.SALARY
          FROM EMPLOYEES EMP
         WHERE EMP.JOB_ID = (SELECT EMP.JOB_ID
                               FROM EMPLOYEES EMP
                              WHERE EMP.EMPLOYEE_ID = 141)
           AND EMP.SALARY > (SELECT EMP.SALARY
                               FROM EMPLOYEES EMP
                              WHERE EMP.EMPLOYEE_ID = 143)
                
                --返回公司工资最少的员工的last_name, JOB_ID和SALARY
                SELECT EMP.LAST_NAME, EMP.JOB_ID, EMP.SALARY
                  FROM EMPLOYEES EMP
                 WHERE EMP.SALARY =
                       (SELECT MIN(EMP.SALARY) FROM EMPLOYEES EMP)
                        --查询最低工资大于50号部门最低工资的部门id和其最低工资
                        SELECT EMP.DEPARTMENT_ID, MIN(EMP.SALARY)
                          FROM EMPLOYEES EMP
                        HAVING MIN(EMP.SALARY) > (SELECT MIN(EMP.SALARY)
                                                    FROM EMPLOYEES EMP
                                                   WHERE EMP.DEPARTMENT_ID = 50)
                         GROUP BY EMP.DEPARTMENT_ID
--
SELECT EMP.DEPARTMENT_ID, MIN(EMP.SALARY)
                          FROM EMPLOYEES EMP
                          GROUP BY emp.department_id
                        HAVING MIN(EMP.SALARY) > (SELECT MIN(EMP.SALARY)
                                                    FROM EMPLOYEES EMP
                                                   WHERE EMP.DEPARTMENT_ID = 50)
--
SELECT EMP.DEPARTMENT_ID, MIN(EMP.SALARY)
                          FROM EMPLOYEES EMP
                          GROUP BY emp.department_id
                        HAVING MIN(EMP.SALARY) > (SELECT MIN(EMP.SALARY)
                                                    FROM EMPLOYEES EMP
                                                   WHERE EMP.DEPARTMENT_ID = 50)
                                                   ORDER BY EMP.DEPARTMENT_ID ASC
/*

多行子查询
1.返回多行
2.使用多行比较操作符
in 等于列表中的任意一个
any 和子查询返回的某一个值比较
all 和子查询返回的所有值比较

*/                                                   
--
/*

返回其他部门中比job_id为'IT_PROG'部门任一工资低的员工的员工号、姓名、job_id以及salary
下面演示any和all

*/
--使用ANY的方式
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG'
AND emp.salary <
ANY(
SELECT emp.salary
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
)
ORDER BY emp.employee_id ASC
--也可以改成下面这种方式,效果是一样的
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG'
AND emp.salary < (
SELECT MAX(emp.salary)
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
)
ORDER BY emp.employee_id ASC

/*

返回其他部门中比job_id为'IT_PROG'部门任意(所有)工资低的员工的员工号、姓名、job_id以及salary

*/

--使用ALL的方式
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG'
AND emp.salary <
ALL(
SELECT emp.salary
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
)
ORDER BY emp.employee_id ASC
--也可以改成下面这种方式,效果是一样的
SELECT emp.employee_id, emp.last_name, emp.job_id, emp.salary
FROM employees emp
WHERE emp.job_id <> 'IT_PROG'
AND emp.salary < (
SELECT MIN(emp.salary)
FROM employees emp
WHERE emp.job_id = 'IT_PROG'
)
ORDER BY emp.employee_id ASC

/*

子查询中的空值问题

*/
--子查询中查到了结果
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id = (
SELECT emp.manager_id
FROM employees emp
WHERE emp.employee_id = 117
)
/*

子查询中没有查到符合条件的数据,所以返回空值给外层查询,所以外层查询自然就查不到任何的数据,
子查询中的空值问题不会报错,只是没有查询结果而已

*/
--子查询中没有查到结果
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id = (
SELECT emp.manager_id
FROM employees emp
WHERE emp.employee_id = 666
)
--
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id NOT IN (
SELECT emp.manager_id
FROM employees emp
)
--
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.employee_id IN (
SELECT emp.manager_id
FROM employees emp
)

--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id IS NULL
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id IN (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id NOT IN (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id != (
SELECT NULL
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id != (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id != NULL
--
SELECT NULL, NULL AS "空空如也", 'abc123', 'hello', '江西赣州于都县' AS "家乡", '深圳' "工作地", emp.last_name, emp.salary
FROM employees emp
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id IN (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = ANY (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)
--
SELECT emp.employee_id, emp.last_name, emp.department_id
FROM employees emp
WHERE emp.department_id = ALL (
SELECT emp.department_id
FROM employees emp
WHERE emp.employee_id = 199
)

/*
子查询练习题
*/
--查询工资最低的员工的信息,last_name, salary
SELECT emp.last_name, emp.salary
FROM employees emp
WHERE emp.salary = (
SELECT MIN(emp.salary)
FROM employees emp
)
--查询平均工资最低的部门信息
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MIN(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id

--查询平均工资最低的部门信息
SELECT dep.department_id 部门编号, dep.department_name AS "部门名称", dep.*
FROM departments dep
WHERE dep.department_id = (
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MIN(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
--查询平均工资最低的部门信息和该部门的平均工资(此题目有点难度)
SELECT dep.department_id 部门编号, dep.department_name AS "部门名称", dep.*,
--(SELECT AVG(emp.salary) AS "平均薪水"
(SELECT AVG(emp.salary)
FROM employees emp
WHERE emp.department_id = dep.department_id) AS "平均工资"
FROM departments dep
WHERE dep.department_id = (
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MIN(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)

--查询平均工资最高的job的信息(万一有多个job_id的平均工资等于最高平均工资,那就不能用=等号了,应该改成in)
SELECT job.*
FROM jobs job
WHERE job.job_id = (
SELECT  
emp.job_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT  
MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.job_id
)
GROUP BY emp.job_id
)

--把=等号改成in
SELECT job.*
FROM jobs job
--这里改成in
WHERE job.job_id in (
SELECT  
emp.job_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT  
MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.job_id
)
GROUP BY emp.job_id
)

--查询平均工资高于公司平均工资的部门有哪些?
SELECT dep.*, (SELECT AVG(emp.salary) FROM employees emp WHERE emp.department_id = dep.department_id )
FROM departments dep
WHERE dep.department_id IN (
SELECT emp.department_id
--, AVG(emp.salary)
FROM employees emp
GROUP BY emp.department_id
HAVING AVG(emp.salary) > (
SELECT AVG(emp.salary)
FROM employees emp
)
)
--
SELECT emp.department_id, AVG(emp.salary) AS avg_salary
FROM employees emp
GROUP BY emp.department_id
HAVING AVG(emp.salary) > (
SELECT AVG(emp.salary)
FROM employees emp
)
ORDER BY avg_salary DESC
--

--查询公司中所有manager的详细信息
SELECT emp.*
FROM employees emp
WHERE emp.employee_id IN (
SELECT emp.manager_id
FROM employees emp
WHERE emp.manager_id IS NOT NULL
GROUP BY emp.manager_id
)
--另一种写法
SELECT emp.*
FROM employees emp
WHERE emp.employee_id IN (
SELECT emp.manager_id
FROM employees emp
)

--各个部门中 最高工资中最低的那个部门的 最低工资是多少?
SELECT emp.department_id, MAX(emp.salary)
FROM employees emp
GROUP BY emp.department_id
ORDER BY MAX(emp.salary) ASC
--
SELECT MIN(MAX(emp.salary))
FROM employees emp
GROUP BY emp.department_id
--
SELECT emp.department_id, MAX(emp.salary), MIN(emp.salary)
FROM employees emp
HAVING MAX(emp.salary) = (
SELECT MIN(MAX(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
--
SELECT MIN(emp.salary)
FROM employees emp
WHERE emp.department_id IN (
--WHERE emp.department_id = (
SELECT emp.department_id
FROM employees emp
HAVING MAX(emp.salary) = (
SELECT MIN(MAX(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
--
SELECT * FROM employees emp WHERE emp.department_id = 10
--
SELECT MIN(emp.salary)
FROM employees emp
WHERE emp.department_id IN (40, 60, 80)
--
SELECT emp.department_id, MAX(emp.salary)
FROM employees emp
GROUP BY emp.department_id
HAVING MAX(emp.salary) = 24000 OR MAX(emp.salary) = 14000


--查询平均工资最高的部门的manager的详细信息:last_name, department_id, email,salary
SELECT emp.department_id, AVG(emp.salary) AS avg_salary
FROM employees emp
GROUP BY emp.department_id
ORDER BY avg_salary DESC
--
SELECT MAX(AVG(emp.salary)) AS MAX_avg_salary
FROM employees emp
GROUP BY emp.department_id
--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
--
SELECT emp.*
FROM employees emp
WHERE emp.department_id IN(
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
--
SELECT last_name AS 名字, department_id AS "部门编号", email 邮箱, salary 薪水, emp.*
FROM employees emp
WHERE emp.employee_id IN (
SELECT emp.manager_id
FROM employees emp
WHERE emp.department_id IN(
SELECT emp.department_id
FROM employees emp
HAVING AVG(emp.salary) = (
SELECT MAX(AVG(emp.salary))
FROM employees emp
GROUP BY emp.department_id
)
GROUP BY emp.department_id
)
)


--查询1999年来公司的员工中的最高工资的那个员工的信息
SELECT emp.salary, emp.*
FROM employees emp
WHERE to_char(emp.hire_date, 'yyyy') = '1999'
ORDER BY emp.salary DESC
--
SELECT MAX(emp.salary)
FROM employees emp
WHERE to_char(emp.hire_date, 'yyyy') = '1999'
--
SELECT emp.salary, emp.*
FROM employees emp
WHERE emp.salary IN (
--WHERE emp.salary = (
SELECT MAX(emp.salary)
FROM employees emp
WHERE to_char(emp.hire_date, 'yyyy') = '1999'
)
AND to_char(emp.hire_date, 'yyyy') = '1999'

--1.查询和Zlotkey相同部门的员工姓名和雇用日期
SELECT emp.last_name AS 员工姓名, emp.hire_date "雇用日期", emp.*
FROM employees emp
--可以把=等号改成in
WHERE emp.department_id = (
SELECT emp.department_id
FROM employees emp
WHERE lower(emp.last_name) = 'zlotkey'
)
--也可以把!=符号改成<>
AND lower(emp.last_name) != 'zlotkey'

--2.查询工资比公司平均工资高的员工的员工号,姓名和工资
SELECT emp.employee_id, emp.last_name, emp.salary
FROM employees emp
WHERE emp.salary > (
SELECT AVG(emp.salary)
FROM employees emp
)

--3.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(这道题目有点难度)
--各个部门的平均工资
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
GROUP BY emp.department_id
--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
WHERE emp.department_id = emp.department_id
GROUP BY emp.department_id
--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
WHERE 20 = 20
GROUP BY emp.department_id
--正确答案
SELECT emp1.employee_id, emp1.last_name, emp1.salary
FROM employees emp1
WHERE emp1.salary > (
SELECT AVG(emp2.salary)
FROM employees emp2
WHERE emp1.department_id = emp2.department_id
GROUP BY emp2.department_id
)
--


--4.查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名
SELECT emp.employee_id, emp.last_name, emp.*
FROM employees emp
WHERE emp.department_id IN (
SELECT emp.department_id
FROM employees emp
--WHERE emp.last_name LIKE '%' || lower('U') || '%'
WHERE emp.last_name LIKE '%u%'
)
AND emp.last_name NOT LIKE '%u%'


--
SELECT *
FROM employees emp
WHERE last_name = 'Pataballa'
--
SELECT *
FROM employees emp
WHERE last_name = 'Pata' || 'balla'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%Pata' || 'bal%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%Patabal%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%' || 'Pata' || 'bal' || '%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%' || upper('p') || 'ata' || 'bal' || '%'
--
SELECT *
FROM employees emp
WHERE last_name LIKE '%' || lower('P') || 'ata' || 'bal' || '%'

--5.查询在部门的location_id为1700的部门工作的员工的员工号
SELECT emp.employee_id, emp.last_name
FROM employees emp
WHERE emp.department_id IN (
SELECT dep.department_id
FROM departments dep
WHERE dep.location_id = 1700
)

--6.查询管理者是King的员工姓名和工资
SELECT emp.last_name AS "员工姓名", emp.salary 薪水, emp.*
FROM employees emp
WHERE emp.manager_id IN(
SELECT emp.employee_id
FROM employees emp
WHERE LOWER(emp.last_name) = 'king'
)


--
SELECT emp.job_id, AVG(emp.salary) AS sal
FROM employees emp
GROUP BY emp.job_id
ORDER BY sal DESC
--
SELECT emp.department_id, AVG(emp.salary) AS sal
FROM employees emp
GROUP BY emp.department_id
ORDER BY sal DESC

--
SELECT emp.job_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) >= 17000 --HAVING关键字也可以放在FROM后面,也可以放在GROUP BY后面
GROUP BY emp.job_id
--HAVING AVG(emp.salary) >= 17000

--
--SELECT MAX(emp.salary)
SELECT AVG(emp.salary), MAX(emp.salary)
--SELECT AVG(emp.salary)
--SELECT emp.salary
FROM employees emp
--HAVING AVG(emp.salary) >= 6400 AND MAX(emp.salary) > 23000
--HAVING AVG(emp.salary) >=  6400
--HAVING AVG(emp.salary) >=  6400
HAVING MAX(emp.salary) > 23000

--
SELECT emp.department_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
GROUP BY emp.department_id
HAVING AVG(emp.salary) > 9000

--
SELECT emp.salary
FROM employees emp
WHERE emp.salary > 6400

--
SELECT emp.department_id, AVG(emp.salary)
FROM employees emp
--HAVING emp.salary > 6400
HAVING AVG(emp.salary) > 6400 AND department_id > 80
GROUP BY emp.department_id

--以下这种写法是错误的
SELECT emp.last_name, emp.salary, emp.employee_id
FROM employees emp
HAVING AVG(emp.salary) > 6400

--
SELECT MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300
--
SELECT AVG(emp.salary)
FROM employees emp
HAVING MAX(emp.salary) > 23500
--
SELECT AVG(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300
--
SELECT AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300
--
SELECT AVG(emp.salary), MAX(emp.salary), SUM(emp.salary), MIN(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6300

--
--SELECT emp.department_id
SELECT emp.department_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6400
GROUP BY emp.department_id
--
SELECT emp.department_id
--SELECT emp.department_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
HAVING AVG(emp.salary) > 6400
GROUP BY emp.department_id

--
SELECT emp.department_id, emp.job_id, AVG(emp.salary), MAX(emp.salary)
FROM employees emp
--HAVING AVG(emp.salary) > 6400
/*
还有一个要注意:HAVING关键字的作用也是过滤数据,HAVING后面可以跟组函数,如
果HAVING要过滤某个字段的话,只能过滤SELECT后面出现了的字段,比
如这里的SELECT emp.department_id, emp.job_id, AVG(emp.salary), MAX(emp.salary)这句话,SELECT后面出
现了department_id和job_id这2个字段,所以HAVING后面只能跟组函数以及department_id和job_id这2个字段
*/
--不等于可以使用<>符号,也可以使用!=符号,如下:
HAVING emp.department_id IN (40, 60, 80, 100) AND (emp.job_id != 'IT' OR emp.job_id <> 'IT')
GROUP BY emp.department_id, emp.job_id

猜你喜欢

转载自blog.csdn.net/czh500/article/details/82796106