[mysql]相关子查询

打印 上一主题 下一主题

主题 1020|帖子 1020|积分 3060

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
相关子查询

相关子查询的概述

我们前面把单行子查询和多行子查询就已经说完了,我们如今要把继续把相关子查询的内容给大家说明确,由于之前用的都是不相关子查询的案例,
我们来谈一谈相关子查询,记着单行子查询和多行子查询是可以进行相关子查询,只是我们刚才写的案例都是相关子查询的案例.
我们看一下,如果子查询的实行依靠于外部查询,用到了外部的表,每次查询的时候都要实行一次外部查询,那么这样的子查询就被我们叫做关联子查询,下面列出了子查询的步骤,
好比我们之前的案例,查询比abel这个人工资高的员工姓名和工资

这里内查询是11000的值,我们外查询的107个值和这11000进行对比,是否满足关系.如果效果是1我们就要,效果是0我们就不要.
而相关子查询就不一样的.
好比

我们这里内查询的表是不是出现了外查询的数据.我们现实步骤是从外查询找到了一条数据,然后送到内查询中去,送进去的值我们看看要怎么用,怎么运算.通过这个运算,返回一个SELECT的效果,可能是一个列也可能是2个列.第三步拿着我们送进去的数据效果和条件比力,然后最后对比效果是1我们就要,不是我们就不要,我们那一个案例来说明
WHERE中的相关子查询

标题1,我们要查询员工工资大于本部分平均工资的员工姓名工资和其部分id
那么我们是不是假如查询的是张三,那么子查询的内容就是张三部分的平均工资,如果查询的是李思,子查询的内容就是李四部分的平均工资,子查询的内容是跟随外部数据的变化而变化的就说明这是相关子查询,
我们来看看怎么做:
首先我们看看
标题查询员工工资大于60号部分平均工资的员工姓名工资和其部分id怎么写
SELECT last_name,salary
FROM employees
WHERE salary>(
              SELECT AVG(salary)
              FROM employees
              WHERE department_id=60)

但是现实是我们要的是本部分,所以60这个值需要修改成外查询的部分,所以我们给外查询的表起个名T1,内查询表起个名T2
SELECT last_name,salary
FROM employees T1
WHERE salary>(
              SELECT AVG(salary)
              FROM employees T2
              WHERE T2.department_id=T1.department_id)
我们实行一下

FROM中的相关子查询

这个子查询我们也可以用在FROM中声明子查询或者说连接子查询的的方法去写这个内容
如果我们的表内里多一个字段是部分的平均工资,那么是不是就可以直接用这个字段来筛选我们的表呢.自然是可行的.解答如下,我们把这两个表连接起来
SELECT last_name,salary
FROM employees T1 JOIN
(SELECT department_id,AVG(salary) avg_salary FROM employees T2 GROUP BY department_id) T2
ON T1.department_id=T2.department_id
WHERE T1.salary>T2.avg_salary


留意这里必须给表的聚合函数起一个别名才能连接使用
ORDER BY中使用子查询

查询员工的id,salary 安装department_name 排序
SELECT employee_id,salary
FROM employees e
ORDER BY(SELECT T1.department_name
          FROM departments T1
          WHERE T1.department_id=e.department_id)
          ASC
结论

子查询除了在GROUP BY和LIMIT中其他地方都可以使用子查询
标题,如果employee表中employee_id
与job_histoty表中的employe_id雷同的数量不小于2输出雷同id的员工的employee_id,last_name和其job_id
employee_id

这里就是要找到我们在job_history中调岗高出2次的员工
我们首先
SELECT employee_id,last_name,job_id FROM employees T1
WHERE (SELECT count(employee_id)
        FROM job_history T2
        WHERE T2.employee_id=T1.employee_id)
        >=2

这里是不是就相当于这个员工出现了2次不同工作的情况,说明调过岗位.
而且这里我们子查询既然出现了外查询的表,那就说明是相关子查询
关键词EXISTS 与NOT EXISTS

这两个关键字代表的是是否存在满足条件的行,一般出现这种情况属于相关子查询,由于如果子查询不和外查询相关的话,这个查询也就一直是FALSE或者一直是TRUE,那么EXISTS关键字就没有意义了.
查询公司管理者的employee_id,last_name,job_id,department_id
方法1:自连接
SELECT DISTINCT T2.manager_id,T1.last_name,T1.job_id,T1.department_id FROM employees T1 JOIN
employees T2 ON T1.employee_id=T2.manager_id

留意这里使用的是T1的字段,如果是T2的字段,代表的含义就是这个id的员工管
理了几个人
方法2:子查询

方法3:EXISTS

这个关键词的含义是把子查询的WHERE当成一个条件,而WHERE会把每一行数据都送进来进行判断,如果判断成功,WHERE就会把这条记载保留下来.所以本质是EXISTS是雷同PYTHON和JAVA中的IF满足条件.也就是说前面SELECT反面跟的字段完全没有意义.
标题查询departments表中不存在于employees中的部分的department_id和department_name
这个标题是不是雷同于我们讲内连接的时候的时候满足员工是空,部分存在的情况
SELECT department_id,department_name FROM departments T2
WHERE NOT EXISTS(SELECT * FROM employees T1
WHERE T1.department_id= T2.department_id)


SELECT employee_id,T2.department_id FROM employees RIGHT JOIN departments T2
ON employees.employee_id IS NULL

更新中的相关子查询

在员工表中添加一个department_name字段,数据为员工对应的部分名称
UPDATE employees e
SET department_name =(SELECT department_name
FROM departments d
WHERE e.department_id=d.department_id)
这个update原来是添加列的,我们如今添加列的值是使用=,每一行都会运行一遍子查询,探求此中这行对应的department_name的值.
这是单行子查询,并且也是相关子查询
删除中的相关子查询

DELETE FROM employees e
WHERE employee_id IN (SELECT employee_id FROM emp_history
WHERE employee_id=e.employee_id)
思索题:谁的工资比Abel高呢,使用那个方法效率高

第一个方法是自连接,直接每个表都连上abel的工资,然后选出大于abel的
SELECT department_id,department_name FROM departments T2
WHERE NOT EXISTS(SELECT * FROM employees T1
WHERE T1.department_id= T2.department_id)
第二个方法是子查询,直接筛选条件,大于abel的
SELECT employee_id FROM employees
WHERE  salary>(SELECT salary FROM employees
WHERE last_name='abel')
结论:多表连接

是方法要用多表连接的方法,如今数据库会主动识别这种可以直接转换为自连接.的子查询,把它转化为自连接,由于DBMS体系都对自连接这种多表查询的方式进行了优化,而子查询是根据未知的表查询后的条件判断.所从前者快.具体原因我们下篇再说

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表