MSYQL 子查询

使用子查询

本章介绍什么是子查询以及如何使用它们。

子查询

SELECT语句 是SQL的查询。迄今为止我们所看到的所有SELECT 语句都是简单查询,即从单个数据库表中检索数据的单条语句。

查询(query)任何SQL语句都是查询。但此术语一般指SELECT语句。

SQL还允许创建子查询(subquery),即嵌套在其他查询中的查询。

为什么要这样做呢?理解这个概念的最好方法是考察几个例子。

利用子查询进行过滤

我们课堂上使用的有两张表,学生信息表和成绩表两个表中。

学生表包含学号,籍贯,生日等信息

成绩表包含的有课程,成绩,考试时间,上课老师等信息

现在,假如需要列出考试成绩不及格的 所有同学,应该怎样检索?下

面列出具体的步骤。

1. 先在成绩表中查出成绩低于60分同学,找到这些同学的学号;

2. 然后学生信息表中按照学号检索出对应的同学名字

SELECT      score     FROM     scores      WHERE     score    <    60   ;

SELECT       name     FROM    students      WHERE

stuid       in       (“xxxxx”,”xxxxx);

select           name,age      from       students       where        stu_id       in        (select  stu_id     from

scores         where     score    <     60) ;

可见,在WHERE 子句中使用子查询能够编写出功能很强并且很灵活的SQL语句。对于能嵌套的子查询的数目没有限制,不过在实际使用时由于性能的限制,不能嵌套太多的子查询

列必须匹配在WHERE 子句中使用子查询(如这里所示),应该保证SELECT 语句具有与WHERE 子句中相同数目的列。通常,子查询将返回单个列并且与单个列匹配,但如果需要也可以使用多个列。

子查询和性能这里给出的代码有效并获得所需的结果。但是,使用子查询并不总是执行这种类型的数据检索的最有效的方法。

子查询:子查询时将一个查询语句嵌套在另一个查询语句中。

内层查询语句的查询结果,可以为外层查询语句提供查询条件,因为在特定的情况下,一个查询语句的条件需要另外一个查询语句来获取,例如现在需要从学生成绩表中查询计算机系学生的各科成绩,那么首先就必须知道哪些课程是计算机系学生选修的,因此必须查询计算机学生选修的课程,然后根据这些课程来查询计算机系学生的各科成绩,通过子查询,可以实现多表之间的查询,子查询中可能包IN,NOT IN,ANY,ALL,EXISTS和NOT EXSITS等关键字,子查询中还可能包含比较运算符,如‘=’,‘!=’,‘>’等;

带IN关键字的子查询

 mysql> select * from employee

    -> where d_id IN

    -> (select d_id from department);

+------+------+--------+------+------+--------------------+

| num  | d_id | name | age  | sex  | homeaddr           |

+------+------+--------+------+------+--------------------+

|    1 | 1001 | 张三   |   26 | 男   | 北京市海定区       |

|    2 | 1002 | 李四   |   24 | 女   | 北京市昌平区       |

|    3 | 1001 | 王五   |   24 | 男   | 湖南长沙市         |

+------+------+--------+------+------+--------------------+

3 rows in set (0.00 sec)


mysql>

查询employee表中的记录,这些记录的d_id字段必须没有在department表中出现过。

mysql> select * from employee

    -> where d_id NOT IN

    -> (select d_id from department );

+------+------+------+------+------+----------+

| num  | d_id | name | age  | sex  | homeaddr |

+------+------+------+------+------+----------+

|    4 | 1004 | Aric |   15 | 男   | England  |

+------+------+------+------+------+----------+

1 row in set (0.00 sec)

 带比较运算符的子查询

子查询可以使用比较运算符(=,!=,>,<,>=,<=,<>)等

示例数据表

mysql> select   *    from   computer_stu,scholarship;

+------+------+-------+-------+-------+

| id   | name | score | level | score |

+------+------+-------+-------+-------+

| 1001 | Lily |    85 |     1 |    90 |

| 1001 | Lily |    85 |     2 |    80 |

| 1001 | Lily |    85 |     3 |    70 |

| 1002 | Tom  |    91 |     1 |    90 |

| 1002 | Tom  |    91 |     2 |    80 |

| 1002 | Tom  |    91 |     3 |    70 |

| 1003 | Jim  |    87 |     1 |    90 |

| 1003 | Jim  |    87 |     2 |    80 |

| 1003 | Jim  |    87 |     3 |    70 |

| 1004 | Aric |    77 |     1 |    90 |

| 1004 | Aric |    77 |     2 |    80 |

| 1004 | Aric |    77 |     3 |    70 |

| 1005 | Lucy |    65 |     1 |    90 |

| 1005 | Lucy |    65 |     2 |    80 |

| 1005 | Lucy |    65 |     3 |    70 |

| 1006 | Andy |    99 |     1 |    90 |

| 1006 | Andy |    99 |     2 |    80 |

| 1006 | Andy |    99 |     3 |    70 |

| 1007 | Ada  |    85 |     1 |    90 |

| 1007 | Ada  |    85 |     2 |    80 |

| 1007 | Ada  |    85 |     3 |    70 |

| 1008 | Jeck |    70 |     1 |    90 |

| 1008 | Jeck |    70 |     2 |    80 |

| 1008 | Jeck |    70 |     3 |    70 |

+------+------+-------+-------+-------+

24 rows in set (0.00 sec)

mysql>

从computer_stu表中查询获得一等奖学金的学生的学号,姓名和分数

mysql> select id,name,score from computer_stu where score >= (select score from scholarship where level=1);

+------+------+-------+

| id   | name | score |

+------+------+-------+

| 1002 | Tom  |    91 |

| 1006 | Andy |    99 |

+------+------+-------+

2 rows in set (0.00 sec)

在department表中查询那些部门没有年龄为24岁的员工;

mysql> select d_id,d_name from department

    -> where d_id NOT IN

    -> (select d_id from employee where age=24);

+------+-----------+

| d_id | d_name    |

+------+-----------+

| 1003 | 销售部    |

+------+-----------+

1 row in set (0.00 sec)

 带EXISTS 关键字的子查询

EXISTS关键字表示存在,使用EXISTS关键字时,内层查询不会反悔查询记录,而是返回一个真假值,当返回真是外层查询语句进行查询,当返回假时,外层语句不进行查询或者查询 不出任何结果。

例:如果department表中存在d_id取值为1003的记录,则查询employee表的记录:

mysql> select * from employee

    -> where EXISTS

    -> (select d_name from department where d_id =1003)

    -> ;

+------+------+--------+------+------+--------------------+

| num  | d_id | name | age  | sex  | homeaddr           |

+------+------+--------+------+------+--------------------+

|    1 | 1001 | 张三   |   26 | 男   | 北京市海定区       |

|    2 | 1002 | 李四   |   24 | 女   | 北京市昌平区       |

|    3 | 1001 | 王五   |   24 | 男   | 湖南长沙市         |

|    4 | 1004 | Aric   |   15 | 男   | England            |

+------+------+--------+------+------+--------------------+

4 rows in set (0.00 sec)


mysql>

例:如果department表中存在d_id取值为1004的记录,则查询emloyee表的记录;

mysql>

mysql> select * from employee

    -> where EXISTS

    -> (select d_name from department where d_id=0);

Empty set (0.00 sec)


mysql>


例:如果department表中存在d_id取值为1003的记录,则查询employee表中age大于24的记录;

mysql>

mysql> select * from employee where age>24 and EXISTS

    -> (select d_name from department where d_id=1003);

+------+------+--------+------+------+--------------------+

| num  | d_id | name | age  | sex  | homeaddr           |

+------+------+--------+------+------+--------------------+

|    1 | 1001 | 张三   |   26 | 男   | 北京市海定区       |

+------+------+--------+------+------+--------------------+

1 row in set (0.00 sec)

mysql>

带ANY关键字的子查询

 ANY关键字表示满足其中任一条件,使用ANY关键字时,是要满足内层查询语句返回的结果中的任何一个,就可以通过该条件来执行外层查询语句。

例:查询到底哪位同学能获得奖学金:

mysql>

mysql> select * from computer_stu where score >= ANY

    -> (select score from scholarship);

+------+------+-------+

| id   | name | score |

+------+------+-------+

| 1001 | Lily |    85 |

| 1002 | Tom  |    91 |

| 1003 | Jim  |    87 |

| 1004 | Aric |    77 |

| 1006 | Andy |    99 |

| 1007 | Ada  |    85 |

| 1008 | Jeck |    70 |

+------+------+-------+

7 rows in set (0.00 sec)

mysql>

带ALL关键字的子查询

ALL关键字表示满足所有条件,使用ALL关键字时,只有满足内层查询语句返回的所有结果,才可以执行外层查询语句。

例:从computer_stu表中查询出那些同学可以获得一等奖学金;

mysql>

mysql> select * from computer_stu

    -> where score >= ALL

    -> (select score from scholarship);

+------+------+-------+

| id   | name | score |

+------+------+-------+

| 1002 | Tom  |    91 |

| 1006 | Andy |    99 |

+------+------+-------+

2 rows in set (0.00 sec)

mysql>

注:ANY关键字和ALL关键字的使用方式是一样的,但是俩这有很大的区别,使用ANY关键字时,只要满足内层查询语句返回的结果中的任何一个,就可以通过该条件来执行外层查询语句,而ALL关键字刚好相反,只有满足内层查询语句返回的所有结果,才可以执行外层查询语句。

合并查询结果(具有去重功能)

合并查询结果是将多个select语句的查询结果合并在一起,因某种情况下,需要将几个select语句查询出来的结果合并起来显示,例如现在需要查询公司甲和公司乙这俩个公司所有的员工信息,然后将俩次的查询结果合并到一起,进行合并操作使用 UNION和UNION ALL关键字。

格式:select 语句1

    UNION |  UNION ALL

   select  语句2

    UNION |  UNION ALL

例:从department表和employee表中查询d_id字段的取值,然后通过UNION关键字将结果合并到一起。

mysql>

mysql> select d_id from department

    -> UNION

    -> select d_id from employee;

+------+

| d_id |

+------+

| 1001 |

| 1002 |

| 1003 |

| 1004 |

+------+

4 rows in set (0.00 sec)

mysql>






Robbers:The content of this article is for reference only. If a mistake is found, it can be a private author. If it is found identical, please inform the author that I will indicate the source.

你可能感兴趣的:(MSYQL 子查询)