✍️
炼码教程 - SQL 边学边练
  • License
  • 介绍 Introduction
    • 目录 Content
  • Level 1
    • Hello SQL
    • 简单的 SELECT 语句
    • 简单的 INSERT 语句
    • 简单的 UPDATE 语句
    • 简单的 DELETE 语句
  • Level 2
    • 简单的数据库和数据表操作
      • 创建数据库
      • 创建数据表
      • 删除数据表
      • 删除数据库
    • 约束
      • 主键约束
      • 自增长约束
    • 常见数据类型
  • Level 3
    • SELECT进阶
      • WHERE 条件子句
      • ORDER BY 与 LIMIT
      • SELECT DISTINCT
    • Function 函数
      • AVG()
      • COUNT()
      • MAX()
      • MIN()
      • SUM()
      • ROUND()
      • NULL()
  • Level 4
    • Level 4 时间
  • Level 5
    • Level 5 多表单联合
    • 外键
    • 别名
    • 多表联结
      • INNER JOIN
      • LEFT JOIN
      • RIGHT JOIN
      • OUTER JOIN
  • Level 6
    • Level 6 临时表单
    • GROUP BY
    • HAVING
    • 子查询
      • SELECT 语句中的子查询
      • INSERT 语句中的子查询
      • UPDATE 语句中的子查询
      • DELETE 语句中的子查询
      • 多行子查询
      • 多列子查询
      • HAVING 子句中的子查询
      • 内联视图子查询
  • Level 7
    • Level 7 索引
  • Level 8
    • Level 8 事务 Transaction
  • Level 9
    • Level 9 复杂的SQL查询
  • Level MAX
    • Level 10 变量和循环
  • 附录 Appendix
    • 数据类型参考手册
    • 函数 Function
    • 通配符
    • 演示数据库
    • common
    • Bug 001
Powered by GitBook
On this page
  • 1. 多行子查询使用IN操作符号
  • 1.1 实例
  • 1.2 总结
  • 练习题
  • 2. 多行子查询使用ANY操作符
  • 2.1 实例
  • 2.1 总结
  • 练习题
  • 3. 多行子查询使用ALL操作符
  • 3.1 实例
  • 3.2 总结
  • 练习题

Was this helpful?

  1. Level 6
  2. 子查询

多行子查询

多行子查询即是子查询的返回结果是多行数据。当主查询语句的条件语句中引用子查询结果时必须用多行比较符号(IN,ALL, ANY)来进行比较。

其中

IN 的含义是匹配子查询结果中的任一个值即可("IN" 操作符,能够测试某个值是否在一个列表中)

ALL 则必须要符合子查询的所有值才可

ANY 要符合子查询结果的任何一个值即可。

而且须注意ALL 和ANY 操作符不能单独使用,而只能与单行比较符(=、>、< 、>= 、<= 、<>)结合使用。

1. 多行子查询使用IN操作符号

1.1 实例

查询国籍为'USA'的所有教师所授课程名称:

SELECT name
FROM   courses
WHERE  teacher_id IN 
       ( SELECT id 
         FROM teachers 
         WHERE country='USA');

执行查询结果为:

mysql> SELECT name
    -> FROM   courses
    -> WHERE  teacher_id IN
    ->        ( SELECT id
    ->          FROM teachers
    ->          WHERE country='USA');
+-------------------------+
| name                    |
+-------------------------+
| System Design           |
| Django                  |
| Artificial Intelligence |
| Java P6+                |
+-------------------------+
4 rows in set (0.00 sec)

1.2 总结

通过前面的实例学习,我们总结了带有IN的SELECT子查询方法

语法

SELECT column_name(s)
FROM table_name
WHERE column_name in
   (SELECT column_name
   FROM table_name)

练习题

查询所有年龄大于20岁的老师所教的所有课程的课程名。

SELECT name
FROM courses
WHERE teacher_id IN 
    (SELECT id
     FROM teachers
     WHERE age > 20);

目标输出结果

mysql> SELECT name
    -> FROM courses
    -> WHERE teacher_id IN
    ->  (SELECT id
    ->      FROM teachers
    ->      WHERE age > 20);
+-------------------------+
| name                    |
+-------------------------+
| Advanced Algorithms     |
| System Design           |
| Django                  |
| Web                     |
| Artificial Intelligence |
| Java P6+                |
| Object Oriented Design  |
+-------------------------+
7 rows in set (0.00 sec)

2. 多行子查询使用ANY操作符

ANY 要符合子查询结果的任何一个值即可

2.1 实例

使用课程表courses和教师表teachers

查询有一门授课学生上课人数超过“Southern Emperor”的任意一门授课人数的教师姓名

SELECT name
FROM teachers
WHERE id IN
    (SELECT DISTINCT teacher_id
     FROM courses
     WHERE student_count > ANY( SELECT student_count
                                FROM courses
                                WHERE teacher_id = ( SELECT id
                                                     FROM teachers
                                                     WHERE name = 'Southern Emperor') )
     ) AND
     ( id <> (SELECT id
              FROM teachers
              WHERE name = 'Southern Emperor') );

执行输出结果

mysql> SELECT name
    -> FROM teachers
    -> WHERE id IN
    ->  (SELECT DISTINCT teacher_id
    ->      FROM courses
    ->      WHERE student_count > ANY( SELECT student_count
    ->                                 FROM courses
    ->                                 WHERE teacher_id = ( SELECT id
    ->                                                      FROM teachers
    ->                                                      WHERE name = 'Southern Emperor') )
    ->      ) AND
    ->      ( id <> (SELECT id
    ->               FROM teachers
    ->               WHERE name = 'Southern Emperor') );
+-----------------+
| name            |
+-----------------+
| Eastern Heretic |
| Western Venom   |
+-----------------+
2 rows in set (0.02 sec)

上面的SQL语句比较长,但是拆开理解就会非常容易。

2.1 总结

通过以上实例学习我们可以总结使用ANY的多行子查询使用方法

语法

SELECT column_name(s)
FROM table_name
WHERE column_name in
   ANY(SELECT column_name
   FROM table_name)

练习题

查询有一门课程授课开课时间大于‘Western Venom’教师任意一门开课时间的教师姓名

3. 多行子查询使用ALL操作符

ALL 则必须要符合子查询的所有值才可

3.1 实例

使用课程表courses和教师表teachers

查询有一门授课学生上课人数超过“Western Venom”的所有授课人数的教师姓名

SELECT name
FROM teachers
WHERE id IN
    (SELECT DISTINCT teacher_id
     FROM courses
     WHERE student_count > ALL( SELECT student_count
                                FROM courses
                                WHERE teacher_id = ( SELECT id
                                                     FROM teachers
                                                     WHERE name = 'Western Venom') )
     );

执行输出结果

mysql> SELECT name
    -> FROM teachers
    -> WHERE id IN
    ->  (SELECT DISTINCT teacher_id
    ->      FROM courses
    ->      WHERE student_count > ALL( SELECT student_count
    ->                                 FROM courses
    ->                                 WHERE teacher_id = ( SELECT id
    ->                                                      FROM teachers
    ->                                                      WHERE name = 'Western Venom') )
    ->      );
+-----------------+
| name            |
+-----------------+
| Eastern Heretic |
+-----------------+
1 row in set (0.00 sec)

3.2 总结

通过以上实例学习,我们可以总结ALL的使用方法

语法

SELECT column_name(s)
FROM table_name
WHERE column_name in
   ALL(SELECT column_name
   FROM table_name)

练习题

查询有一门课程授课开课时间大于‘Eastern Heretic’教师任意一门开课时间的教师姓名

PreviousDELETE 语句中的子查询Next多列子查询

Last updated 4 years ago

Was this helpful?