sql语句学习教程14_select_select查询_sql查询语句_sql子查询

教程发布:风哥 教程分类:MySQL教程 更新日期:2020-03-05 浏览学习:3038

1.简单子查询
根据子查询返回数据的行数,对子查询分类为:单行子查询、多行子查询;
根据返回的结果集划分:子查询返回单一值(标量子查询)、一个行(行子查询)、一个列(列子查询)、一个表(表子查询)。
哥教程案例1:
统计当前部门和员工的数量,这里是把子查询当列,所以返回的结果只能是单一值的。
fgedu.net@ mysql>select NOW() 当前时间,
  (select COUNT(*)from bm) 部门数量,
  (select COUNT(*)from yg) 员工人数  from dual;
风哥教程案例2:
这里的子查询是为IN操作提供值的范围,所以返回的可以有多笔记录,但是每笔记录只有一列值
fgedu.net@ mysql>select EMPLOYEE_ID,last_name,MANAGER_ID,job_id
from yg
where EMPLOYEE_ID in (select MANAGER_ID from yg);
风哥教程案例3:
这里的子查询是当做视图,所以要指定别名,可以有多个列和多行数据返回。
fgedu.net@ mysql>select MAX(salary),country_id
from (select a.salary,department_id,location_id,c.country_id
           from yg a
               join bm b using (department_id)
               join dd c using (location_id)
           ) d
group by country_id;
风哥教程案例4:exists
exists,只要存在符合条件的,就返回结果
fgedu.net@ mysql>select * from yg
where exists(select * from bm where department_id=101);
select * from yg
where not exists(select * from bm where department_id=100);

2.复杂子查询
SQL语句关联表很多、条件很复杂的查询,都可以看做复杂查询,这里,我们将多于2级的子查询视作复杂子查询来进行讲解。下面,我们用案例来解析。
风哥教程案例1:查询在中国的部门里面工作的所有的员工,用三级嵌套子查询实现
fgedu.net@ mysql>select first_name,last_name from yg
where department_id in
     (select department_id from bm
       where location_id in
          (select location_id from dd
            where country_id in
               (select country_id from gj
                where country_name='China'
                )
           )
       );
风哥教程案例2:查询所有工资低于平均水平值的人,而且是IT部门的员工
fgedu.net@ mysql>select last_name,salary from yg
where department_id in (
    select department_id from bm
    where department_name in ('桌面支持','信息技术支持','网络运营中心','IT 信息化')
     )
  and SALARY < (select AVG(salary) from yg);
其实不管多复杂的SQL语句,都要思路清晰的一级一级解析,慢慢就会熟练,我们永远不建议用户写出太复杂的多层级的嵌套SQL语句,尤其是在MySQL中,这可能会成为噩梦。

3.多行子查询
我们先来看一个例子:
风哥教程查询1:谁比bell工资高(单行子查询)
fgedu.net@ mysql> select last_name from yg where SALARY>(select salary from yg where last_name='Bell');
64 rows in set (0.00 sec)
风哥教程查询2: 谁比Mr.Taylor的工资高(多行子查询)
fgedu.net@ mysql> select last_name from yg where SALARY>(select salary from yg where last_name='Taylor');
ERROR 1242 (21000): Subquery returns more than 1 row
错误提示说的很明白:子查询返回了超过一行的记录数。
我们来单独执行一下错误语句的子查询:
fgedu.net@ mysql> select first_name,salary from yg where last_name='Taylor';
+------------+---------+
| first_name | salary  |
+------------+---------+
| Jonathon   | 8600.00 |
| Winston    | 3200.00 |
+------------+---------+
2 rows in set (0.00 sec)
这是程序中经常遇到的坑,设计的时候,可能正常流程非常顺畅,但实际一上线,重名的问题,用户输入、采集数据不规范等等各种可能,会导致当初的SQL语句在某些特定条件下报错。

解决这种问题的方法:比较符号后面,子查询前面加上ALL关键字:
>all、< all、>= all、<= all、= all、!=a11、<>all
例如:
fgedu.net@ mysql> select last_name,salary from yg
where SALARY > all (select salary from yg where last_name='Taylor');
当然,你也可以取值的时候,就取最大值,确保返回的记录数唯一,例如:
fgedu.net@ mysql> select last_name,salary from yg
where SALARY >(select MAX(salary) from yg where last_name='Taylor');

另外还有一个ANY关键字,用来将一个值与一个列表中的任何值进行比较,可以有如下形式:
>any、<any、>=any、<=any、=any 、!=any、<>any
例如:
fgedu.net@ mysql> select last_name,salary from yg where SALARY = any
(select salary from yg where last_name='itpux011');
select last_name,salary from yg where SALARY < any
(select salary from yg where last_name='itpux011');

网站声明:本文由风哥整理发布,转载请保留此段声明,本站所有内容将不对其使用后果做任何承诺,请读者谨慎使用!
【上一篇】sql语句学习教程15_select_select查询_sql查询语句_sql函数查询
【下一篇】sql语句学习教程13_select_select查询_sql查询语句_sql连接查询