0

我对以下 SQL 查询感到很困惑:

SELECT (SELECT S.name FROM student AS S
    WHERE S.sid = E.sid) AS sname
FROM enrolled as E
WHERE cid='15-455';

SELECT后面应该有一个输出,但是为什么这里还有另一个SELECT呢?如何理解这个查询的逐步含义?

以下是与上述查询具有相同结果的查询,但其含义相当明确:将第二个 SELECT 的输出传递给IN()函数。

SELECT name FROM student
WHERE sid IN ( 
    SELECT sid FROM enrolled
    WHERE cid = '15-445'
);

以下是这个问题的原始表格:

mysql> select * from student;
+-------+--------+------------+------+---------+
| sid   | name   | login      | age  | gpa     |
+-------+--------+------------+------+---------+
| 53666 | Kanye  | kayne@cs   |   39 | 4.00000 |
| 53688 | Bieber | jbieber@cs |   22 | 3.90000 |
| 53655 | Tupac  | shakur@cs  |   26 | 3.50000 |
+-------+--------+------------+------+---------+

mysql> select * from enrolled;
+-------+--------+-------+
| sid   | cid    | grade |
+-------+--------+-------+
| 53666 | 15-445 | C     |
| 53688 | 15-721 | A     |
| 53688 | 15-826 | B     |
| 53655 | 15-445 | B     |
| 53666 | 15-721 | C     |
+-------+--------+-------+

mysql> select * from course;
+--------+------------------------------+
| cid    | name                         |
+--------+------------------------------+
| 15-445 | Database Systems             |
| 15-721 | Advanced Database Systems    |
| 15-826 | Data Mining                  |
| 15-823 | Advanced Topics in Databases |
+--------+------------------------------+
4

3 回答 3

2

在现实生活中,我会说这两个查询只是避免连接的两种令人毛骨悚然的方法。

但是在这种特殊情况下,它们包含在您找到的幻灯片中,以显示可以在多少地方使用嵌套循环。

他们都做与以下相同的事情

SELECT name 
  FROM student s
  JOIN enrolled e
    ON s.sid = e.sid
 WHERE cid = '15-445';

至于您关于第一个查询的逐步含义的问题。如下

  1. 这将遍历“已注册”表中 cid = '15-455' 的每条记录。

     FROM enrolled as E
    WHERE cid='15-455';
    
  2. 对于步骤 1 中的每条记录,它将执行以下查询

    SELECT S.name 
      FROM student AS S
     WHERE S.sid = E.sid;
    
于 2021-07-12T13:39:14.580 回答
1

这个构造:

SELECT (SELECT S.name FROM student S WHERE S.sid = E.sid) AS sname
-------^

称为标量子查询。这是一种特殊类型的子查询,具有两个重要属性:

  • 它返回一列。
  • 它最多返回一行。

在这种情况下,标量子查询也是一个相关子查询,这意味着它通过where子句引用外部查询中的列。

标量子查询几乎可以在任何可以在查询中使用标量(即常量值)的地方使用。他们可以很方便。它们并不完全等同于连接,因为:

  1. 可以inner join过滤值。NULL如果没有返回行,则返回标量子查询。
  2. Ajoin可以乘以行数。如果标量子查询返回多行,则它会返回错误。
于 2021-07-12T15:27:09.497 回答
0

如果您想获取以下信息:

学生姓名 | 客户识别码 | 等级 |

您可以执行以下操作:

select t.name, e.cid, e.grade 
  from enrolled e
  inner join student t on (e.sid = t.sid)

或不加入(用于优化):

select (name from student t where t.sid = e.sid) as name, e.cid, e.grade
  from enrolled e

所以结果是相同的,但在第二个中你要避免加入。

于 2021-07-12T13:43:01.147 回答