第九章 子查询(重点)

第九章 子查询

#查询员工中工资比Abel多的人
#子查询
SELECT e2.last_name,e2.salary
FROM employees e1,employees e2
WHERE e1.last_name=‘Abel’ AND e1.salary<e2.salary;

#子查询
SELECT last_name,salary
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name=‘Abel’
);

#查询可分为单行子查询和多行子查询,也可以分为相关子查询与不相关子查询

#相关子查询:查询工资大于本部门平均工资的员工信息
SELECT last_name,department_id,salary
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
)
GROUP BY department_id;

#不相关子查询:查询工资大于本公司平均工资的员工信息
SELECT last_name,salary
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
)

#查询工资大于149号员工工资的员工的信息
SELECT employee_id,last_name,salary
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE employee_id=149
);

#返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
SELECT 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
);

#返回公司工资最少的员工的last_name,job_id和salary
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(
SELECT MIN(salary)
FROM employees
);

#查询与141号(employee_id)员工的manager_id和department_id相同的其他员工的employee_id,manager_id,department_id

#方式一:不成对比较,单独比较
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;

#方式二:成对比较
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
)
AND employee_id <>141;

#查询与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(141,174))
AND department_id IN
(SELECT department_id
FROM employees
WHERE employee_id IN(141,174))
AND employee_id NOT IN(141,174);

#成对比较
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);

#having中的子查询
#查询最低工资大于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相同,则lacation为’Canada’,其余为’USA’
SELECT employee_id,last_name,
(CASE department_id
WHEN
(SELECT department_id FROM departmentsemployees
WHERE location_id=1800)
THEN ‘Canada’ ELSE ‘USA’ END)
AS location
FROM employees;

#查询书名和类型,其中note值为novel显示小说,law显示法律,
medicine显示医药,cartoon显示卡通,joke显示笑话

SELECT name’书名’,note,
CASE note
WHEN’novel’ THEN’小说’
WHEN’law’THEN’法律’
WHEN’medicine’THEN’医药’
WHEN’cartoon’THEN’卡通’
WHEN’joke’THEN’笑话’
ELSE’其他’
END
AS ‘类型’
FROM books;

#查询书名、库存,其中num值超过30本的,显示滞销,大于0并低于10的,显示畅销,为0的显示需要无货
SELECT nameAS’书名’,num AS’库存’,
CASE WHEN num>30 THEN’滞销’
WHEN 0<num<10 THEN’畅销’
WHEN num=0 THEN’无货’
ELSE ‘正常’
END
AS ‘显示状态’
FROM books;

#子查询的空值情况:因为里面的子查询为空,没有叫Haas的人,所有最终没有返回任何行
SELECT last_name,job_id
FROM employees
WHERE job_id=(
SELECT job_id
FROM employees
WHERE last_name=‘Haas’
)

#非法使用子查询:用等于会报错,因为这个子查询会返回多行数据,把等号改为in即可
SELECT employee_id,last_name
FROM employees
WHERE salary =(
SELECT MIN(salary)
FROM employees
GROUP BY department_id
)

#因为有不同的员工领着相同的最低工资
SELECT employee_id,last_name
FROM employees
WHERE salary IN(
SELECT MIN(salary)
FROM employees
GROUP BY department_id
)

#多行子查询

#多行子查询的操作符:in() any all some(是any的别名,一般用any)

#返回其他job_id中比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’)
AND job_id!=‘IT_PROG’

SELECT* FROM employees
WHERE employee_id!=101;

#返回其他job_id中比job_id为’IT_PROG’部门工资都低的员工号、姓名、job_id以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<(
SELECT MIN(salary)
FROM employees
WHERE job_id=‘IT_PROG’)
AND job_id!=‘IT_PROG’
#或者
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary<ALL(
SELECT salary
FROM employees
WHERE job_id=‘IT_PROG’)
AND job_id!=‘IT_PROG’

#查询平均工资最低的部门id
#方式一:还是方式一用any,all这种容易理解
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary)<=ALL(
SELECT AVG(salary)
FROM employees
GROUP BY department_id
)

#方式二:三个字段别名一定要有,否则报错,every derived table must have its own itias
#每一个保留下的表都要有自己的别名
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
)

#看下面第一个错,第二个正确 :嵌套函数要以其命名别名的方式
SELECT MIN(AVG(salary))
FROM (
SELECT AVG(salary)
FROM employees
GROUP BY department_id
)

SELECT MIN(ll)
FROM (
SELECT AVG(salary)ll
FROM employees
GROUP BY department_id
)kkk

#相关子查询:比较重要,每次都内查询一次
#回顾:查询员工中工资大于本部门平均工资的last_name,salary和其department_id
SELECT last_name,salary,department_id
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
)

#查询员工中工资大于60号部门平均工资的last_name,salary和其department_id
SELECT last_name,salary,department_id
FROM employees
WHERE salary>(
SELECT AVG(salary)
FROM employees
WHERE department_id=60
)

#相关子查询:查询员工中工资大于60号部门平均工资的last_name,salary和其department_id 查询员工中工资大于本部门平均工资的last_name,salary和其department_id
SELECT last_name,salary,department_id
FROM employees e1
WHERE salary>(
SELECT AVG(salary)
FROM employees
WHERE department_id=e1.department_id
)

#在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 e1.department_id,employee_id,salary
FROM employees e1
ORDER BY(
SELECT department_name
FROM departments e2
WHERE e1.department_id=e2.department_id
)ASC;

#查询员工的id,salary,按照department_name进行排序
#如果查询的字段的表之中都有并且两表之间join,应指定表的字段

SELECT employee_id,salary
FROM employees e1
ORDER BY(
SELECT department_id
FROM departments e2
WHERE e1.department_id=e2.department_id
);

#若employees表中employee_id与job_history表中employee_id相同的数目不小于2,输出这些相同的
#id的员工employee_id,last_name,job_id
#下面这个是错误的
SELECT employees.employee_id,last_name,employees.job_id
FROM employees JOIN job_history
ON employees.employee_id=job_history.department_id;

#正确的如下,count(*)可写为count(字段名)
SELECT e.employee_id,last_name,e.job_id
FROM employees e
WHERE 2<=(
#select count() //可以count()或者count(字段)
SELECT COUNT(employee_id)
FROM job_history
WHERE employee_id=e.employee_id
);

#exists与 not exists关键字
#以下两个题是用的自连接
#查询公司员工的的employee_id,last_name,job_id,department_id信息
SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE employee_id NOT IN(
SELECT manager_id
FROM employees
WHERE manager_id IS NOT NULL
);

#查询公司管理者的employee_id,last_name,job_id,department_id信息:自连接,要distinct对管理者去重
SELECT DISTINCT e2.employee_id,e2.last_name,e2.job_id,e2.department_id
FROM employees e1
JOIN employees e2
ON e1.manager_id=e2.employee_id

#查询公司管理者的employee_id,last_name,job_id,department_id信息:用的子查询
SELECT employee_id,last_name,job_id,department_id
FROM employees
WHERE employee_id IN(
SELECT manager_id
FROM employees
);

#查询公司管理者的employee_id,last_name,job_id,department_id信息:用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
)

#查询departments表中,不存在与employees表中的部门的department_id和department_name
#即查出有的部门中没有员工的情况
#方式一:
SELECT d.department_id,d.department_name
FROM employees 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 EXISTS(
SELECT* FROM employees e
WHERE d.department_id=e.department_id
);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据小理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值