IN-子查询

为什么需要子查询?

现实中,很多情况需要进行以下条件的判断

  • 集合成员资格

    某一元素是否是某一个集合的成员

  • 集合之间的比较

    某一个集合是否包含另一个集合

  • 集合基数的测试

    测试集合是否为空

    测试集合是否存在重复元素

子查询定义

出现在 Where 子句中的 Select 语句被称为子查询(subquery),子查询返回了一个集合,可以通过与这个集合的比较来确定另一个查询集合。

基本语法

表达式 [not] in (子查询)

  • 语法中,表达式最简单的形式就是列名或者常数
  • 语义:判断某一表达式的值是否在子查询的结果中

例1

在一张表中查询tom、david同学的信息

+----------------+
| name           |
+----------------+
| tom            |
| david          |
| lily           |
| jony           |
+----------------+

如果没有子查询,我们会这么写

mysql>select * from test where name='tom' or name ='david';
+----------------+
| name           |
+----------------+
| tom            |
| david          |
+----------------+

使用子查询,我们可以这么写.此处直接使用了某一子查询的结果集合(该集合是已知的固定的)

mysql>select * from test where name in ("tom","david");
+----------------+
| name           |
+----------------+
| tom            |
| david          |
+----------------+

例2

欲查询即学过课程001 又学过课程002的同学

+----------------+------------------+
| name           | course           |
+----------------+------------------+
| tom            | 001              |
| tom            | 002              |
| david          | 001              |
+----------------+------------------+

如果没有子查询,可能会这么写

select t1.name
from test as t1, test as t2
where t1.name = t2.name
and t1.course='001'
and t2.course='002'
+----------------+
| name           |
+----------------+
| tom            |
+----------------+

实际上是表对自身做了笛卡儿积

+----------------+------------------+----------------+------------------+
| name           | course           | name           | course           |
+----------------+------------------+----------------+------------------+
| tom            | 001              | tom            | 001              |
| tom            | 002              | tom            | 001              |
| david          | 001              | tom            | 001              |
| tom            | 001              | tom            | 002              |
| tom            | 002              | tom            | 002              |
| david          | 001              | tom            | 002              |
| tom            | 001              | david          | 001              |
| tom            | 002              | david          | 001              |
| david          | 001              | david          | 001              |
+----------------+------------------+----------------+------------------+

然后再进行了挑选。

使用子查询改写

select name
from test
where course = '001'
and name in
(
    select name
    from test
    where course = '002'
)

查询结果

+----------------+
| name           |
+----------------+
| tom            |
+----------------+

这里的逻辑是:从选修了002课程的学生中再选出选修了001课程的同学,思路更加清晰。

posted @ 2019-02-27 22:32  Velscode  阅读(3991)  评论(0编辑  收藏  举报