美文网首页
SQL-DQL(9)子查询

SQL-DQL(9)子查询

作者: 小白201808 | 来源:发表于2018-08-30 09:11 被阅读27次
  1.含义
    出现在其他语句中的select语句,成为子查询或内查询,外部的查询语句,成为主查询或外查询
  2.分类:
    (1)按子查询出现的位置:
     select 后面 (仅支持标量子查询)
     from   后面  (支持表子查询)
(√√)where  或having后面(支持标量子查询,列子查询,行子查询)
     exists 后面 表子查询  
     
    (2)按结果集的行数不同:
      标量子查询(结果集只有一行一列)
      列子查询(结果集只有一行多列)
      行子查询(结果集一行多列)
      表子查询(结果集一般是多行多列)

3 √ where 或 having后面

  标量子查询(一行一列)
  列子查询(一列多行)
  行子查询(一行多列)
  
  特点:1.子查询放在小括号内
       2.子查询一般放在条件的右侧
       3.标量子查询。一般搭配着单行操作符使用 < , > ,<= , >= , <> ,=.
       4.列子查询,一般搭配着多行操作符使用 in,any/some,all;
       5.子查询的执行优先于主查询执行。

√3-1 标量子查询(一行一列)

案例一:查询工资比Abel高的员工的名字?

mysql> #查询工资比Abel高的员工的名字?
mysql> select last_name from employees where salary >(select salary from employees where last_name = 'Abel');
+-----------+
| last_name |
+-----------+
| K_ing     |
| Kochhar   |
| De Haan   |
| Greenberg |
| Russell   |
| Partners  |
| Errazuriz |
| Ozer      |
| Hartstein |
| Higgins   |
+-----------+
10 rows in set (0.09 sec)

案例二:返回job_id 与141号员工相同的,salary比143号员工高的员工的姓名,job_id 和工资

mysql> 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  |
+-------------+----------+---------+
| Nayer       | ST_CLERK | 3200.00 |
| Mikkilineni | ST_CLERK | 2700.00 |
| Bissot      | ST_CLERK | 3300.00 |
| Atkinson    | ST_CLERK | 2800.00 |
| Mallin      | ST_CLERK | 3300.00 |
| Rogers      | ST_CLERK | 2900.00 |
| Ladwig      | ST_CLERK | 3600.00 |
| Stiles      | ST_CLERK | 3200.00 |
| Seo         | ST_CLERK | 2700.00 |
| Rajs        | ST_CLERK | 3500.00 |
| Davies      | ST_CLERK | 3100.00 |
+-------------+----------+---------+
11 rows in set (0.30 sec)

案例三:返回公司工资最少的员工的姓名,工种号,工资。

mysql> #返回公司工资最少的员工的姓名,工种号,工资。
mysql> select last_name ,job_id,salary from employees where salary =(select min(salary) from employees);
+-----------+----------+---------+
| last_name | job_id   | salary  |
+-----------+----------+---------+
| Olson     | ST_CLERK | 2100.00 |
+-----------+----------+---------+
1 row in set (0.35 sec)

案例四:查询最低工资大于50号部门最低工资的部门id 和其最低工资。

mysql> select department_id,min(salary) from employees group by department_id having min(salary) >(select min(salary) from employees where department_id=50);
+---------------+-------------+
| department_id | min(salary) |
+---------------+-------------+
|          NULL |     7000.00 |
|            10 |     4400.00 |
|            20 |     6000.00 |
|            30 |     2500.00 |
|            40 |     6500.00 |
|            60 |     4200.00 |
|            70 |    10000.00 |
|            80 |     6100.00 |
|            90 |    17000.00 |
|           100 |     6900.00 |
|           110 |     8300.00 |
+---------------+-------------+
11 rows in set (0.35 sec)

√3-2 列子查询(一列多行)

案例一:返回location_id是1400或1700的部门中的所有员工的姓名

mysql> select last_name from employees where department_id in(select distinct department_id from departments where location_id in(1400, 1700));
+------------+
| last_name  |
+------------+
| Hunold     |
| Ernst      |
| Austin     |
| Pataballa  |
| Lorentz    |
| Whalen     |
| Raphaely   |
| Khoo       |
| Baida      |
| Tobias     |
| Himuro     |
| Colmenares |
| K_ing      |
| Kochhar    |
| De Haan    |
| Greenberg  |
| Faviet     |
| Chen       |
| Sciarra    |
| Urman      |
| Popp       |
| Higgins    |
| Gietz      |
+------------+
23 rows in set (0.13 sec)

案例二:返回其他部门中比 job_id 为 'it _ prog'部门所有工资都低的员工 的员工号,姓名,jop_id 以及salary。

mysql> select employee_id ,last_name,salary from employees where salary < all(select salary from employees where job_id ='it_prog');
+-------------+-------------+---------+
| employee_id | last_name   | salary  |
+-------------+-------------+---------+
|         115 | Khoo        | 3100.00 |
|         116 | Baida       | 2900.00 |
|         117 | Tobias      | 2800.00 |
|         118 | Himuro      | 2600.00 |
|         119 | Colmenares  | 2500.00 |
|         125 | Nayer       | 3200.00 |
|         126 | Mikkilineni | 2700.00 |
|         127 | Landry      | 2400.00 |
|         128 | Markle      | 2200.00 |
|         129 | Bissot      | 3300.00 |
|         130 | Atkinson    | 2800.00 |
|         131 | Marlow      | 2500.00 |
|         132 | Olson       | 2100.00 |
|         133 | Mallin      | 3300.00 |
|         134 | Rogers      | 2900.00 |
|         135 | Gee         | 2400.00 |
|         136 | Philtanker  | 2200.00 |
|         137 | Ladwig      | 3600.00 |
|         138 | Stiles      | 3200.00 |
|         139 | Seo         | 2700.00 |
|         140 | Patel       | 2500.00 |
|         141 | Rajs        | 3500.00 |
|         142 | Davies      | 3100.00 |
|         143 | Matos       | 2600.00 |
|         144 | Vargas      | 2500.00 |
|         180 | Taylor      | 3200.00 |
|         181 | Fleaur      | 3100.00 |
|         182 | Sullivan    | 2500.00 |
|         183 | Geoni       | 2800.00 |
|         185 | Bull        | 4100.00 |
|         186 | Dellinger   | 3400.00 |
|         187 | Cabrio      | 3000.00 |
|         188 | Chung       | 3800.00 |
|         189 | Dilly       | 3600.00 |
|         190 | Gates       | 2900.00 |
|         191 | Perkins     | 2500.00 |
|         192 | Bell        | 4000.00 |
|         193 | Everett     | 3900.00 |
|         194 | McCain      | 3200.00 |
|         195 | Jones       | 2800.00 |
|         196 | Walsh       | 3100.00 |
|         197 | Feeney      | 3000.00 |
|         198 | OConnell    | 2600.00 |
|         199 | Grant       | 2600.00 |
+-------------+-------------+---------+
44 rows in set (0.00 sec)

解法2:
mysql> select employee_id ,last_name,salary from employees where salary <(select min(salary) from employees where job_id ='it_prog');


√3-3 行子查询(一行多列或多行多I列)使用频率不高

案例一:查询员工编号最小并且工资最高的员工信息。

mysql> select * from employees where employee_id =(select min(employee_id) from employees) and salary = (select max(salary) from employees);
+-------------+------------+-----------+-------+--------------+---------+----------+----------------+------------+---------------+---------------------+
| employee_id | first_name | last_name | email | phone_number | job_id  | salary   | commission_pct | manager_id | department_id | hiredate            |
+-------------+------------+-----------+-------+--------------+---------+----------+----------------+------------+---------------+---------------------+
|         100 | Steven     | K_ing     | SKING | 515.123.4567 | AD_PRES | 24000.00 |           NULL |       NULL |            90 | 1992-04-03 00:00:00 |
+-------------+------------+-----------+-------+--------------+---------+----------+----------------+------------+---------------+---------------------+
1 row in set (0.08 sec)

mysql> 

4 √ select 后面 (不常用)

案例一:查询每个部门的员工个数

mysql> select d.*,(select count(*) from employees e where e.department_id = d.department_id) 员工个数 from departments d;
+---------------+-----------------+------------+-------------+--------+
| department_id | department_name | manager_id | location_id | 员工个数   |
+---------------+-----------------+------------+-------------+--------+
|            10 | Adm             |        200 |        1700 |      1 |
|            20 | Mar             |        201 |        1800 |      2 |
|            30 | Pur             |        114 |        1700 |      6 |
|            40 | Hum             |        203 |        2400 |      1 |
|            50 | Shi             |        121 |        1500 |     45 |
|            60 | IT              |        103 |        1400 |      5 |
|            70 | Pub             |        204 |        2700 |      1 |
|            80 | Sal             |        145 |        2500 |     34 |
|            90 | Exe             |        100 |        1700 |      3 |
|           100 | Fin             |        108 |        1700 |      6 |
|           110 | Acc             |        205 |        1700 |      2 |
|           120 | Tre             |       NULL |        1700 |      0 |
|           130 | Cor             |       NULL |        1700 |      0 |
|           140 | Con             |       NULL |        1700 |      0 |
|           150 | Sha             |       NULL |        1700 |      0 |
|           160 | Ben             |       NULL |        1700 |      0 |
|           170 | Man             |       NULL |        1700 |      0 |
|           180 | Con             |       NULL |        1700 |      0 |
|           190 | Con             |       NULL |        1700 |      0 |
|           200 | Ope             |       NULL |        1700 |      0 |
|           210 | IT              |       NULL |        1700 |      0 |
|           220 | NOC             |       NULL |        1700 |      0 |
|           230 | IT              |       NULL |        1700 |      0 |
|           240 | Gov             |       NULL |        1700 |      0 |
|           250 | Ret             |       NULL |        1700 |      0 |
|           260 | Rec             |       NULL |        1700 |      0 |
|           270 | Pay             |       NULL |        1700 |      0 |
+---------------+-----------------+------------+-------------+--------+
27 rows in set (0.00 sec)

4 √ from 后面 (不常用)

将子查询充当一张表,要求必须起别名。

案例1:查询每个部门的平均工资的工资等级

mysql> select ag_dep.* ,g.grade_level from (select avg(e.salary) ag, department_id from employees e group by department_id) ag_dep join job_grades g on ag_dep.ag between lowest_sal and highest_sal;
+--------------+---------------+-------------+
| ag           | department_id | grade_level |
+--------------+---------------+-------------+
|  7000.000000 |          NULL | C           |
|  4400.000000 |            10 | B           |
|  9500.000000 |            20 | C           |
|  4150.000000 |            30 | B           |
|  6500.000000 |            40 | C           |
|  3475.555556 |            50 | B           |
|  5760.000000 |            60 | B           |
| 10000.000000 |            70 | D           |
|  8955.882353 |            80 | C           |
| 19333.333333 |            90 | E           |
|  8600.000000 |           100 | C           |
| 10150.000000 |           110 | D           |
+--------------+---------------+-------------+
12 rows in set (0.40 sec)

5 √ exists 后面(相关子查询)(不常用)

语法:
select(完整的查询语句)
结果:(0/1)

案例一:查询有员工的部门名

mysql> select department_name from departments d where exists (select * from employees e where d.department_id = e.department_id);
+-----------------+
| department_name |
+-----------------+
| Adm             |
| Mar             |
| Pur             |
| Hum             |
| Shi             |
| IT              |
| Pub             |
| Sal             |
| Exe             |
| Fin             |
| Acc             |
+-----------------+
11 rows in set (0.00 sec)

注:这是本人的学习笔记及练习,如果有错误的地方望指出一起讨论,谢谢!

相关文章

  • SQL-DQL(9)子查询

    3 √ where 或 having后面 √3-1 标量子查询(一行一列) 案例一:查询工资比Abel高的员工的...

  • 9、子查询

    单行子查询 select * from emp where sal > (selectsal from emp w...

  • SQL-DQL(10)分页查询

    1. 语法:(以SQL199语法为标准) √ 2. 练习 案例一:查询前5条员工信息 案例二:查询第11 至25条...

  • SQL-DQL(11)联合查询

    √ 1.含义 √ 2.练习 案例一:查询部门编号>90 或者邮箱包含e的员工信息 案例二:查询中国用户中男性的信息...

  • SQL-DQL(6)之分组查询

    语法: 注意: √一. 简单分组查询练习 √二. 添加筛选条件分组 √三. 按表达式/函数/别名分组查询 √. 四...

  • SQL-DQL之条件查询(2)

    1.条件查询: 2.筛选条件的分类 一. 按条件表达式筛选简单条件运算符:> , <, = , >= , <= ,...

  • SQL-DQL(3)之排序查询

    语法 √排序查询练习 √额外练习 注:这是本人的学习笔记和练习,如果有错误的地方望指出一起讨论,谢谢!

  • 9. 使用子查询

    使用子查询 查询(query) 任何SQL 语句都是查询,但此术语一般指SELECT 语句。 子查询(subque...

  • Oracel_子查询

    SQL子查询 子查询语法 子查询 (内查询) 在主查询之前一次执行完成。 子查询的结果被主查询(外查询)使用 。 ...

  • Oracle | 子查询和伪列

    1. 子查询 (1)单行子查询 (2)多行子查询 1)ANY子查询 2)ALL 子查询 2. 伪列...

网友评论

      本文标题:SQL-DQL(9)子查询

      本文链接:https://www.haomeiwen.com/subject/kqxrwftx.html