为什么一个SELECT的输出可以是另一个SELECT?
Why the output of a SELECT can be another SELECT?
我对以下 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 |
+--------+------------------------------+
在现实生活中,我会说这两个查询只是避免连接的两种令人毛骨悚然的方法。
但在这种特殊情况下,它们包含在您找到的幻灯片中,以显示可以在多少地方使用嵌套循环。
他们都和下面的一样
SELECT name
FROM student s
JOIN enrolled e
ON s.sid = e.sid
WHERE cid = '15-445';
关于你的第一个查询的分步含义问题。就是下面
这将遍历“已注册”table 中 cid = '15-455' 的每条记录。
FROM enrolled as E
WHERE cid='15-455';
对于第 1 步中的每条记录,它将执行以下查询
SELECT S.name
FROM student AS S
WHERE S.sid = E.sid;
如果你想获取如下信息:
学生姓名 |客户ID |年级 |
你可以这样做:
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
所以结果是一样的,但在第二个中你要避免连接。
这个结构:
SELECT (SELECT S.name FROM student S WHERE S.sid = E.sid) AS sname
-------^
称为 标量子查询 。这是一种特殊类型的子查询,具有两个重要属性:
- 是returns一栏。
- 最多returns一行。
在这种情况下,标量子查询也是一个相关子查询,这意味着它通过where
子句。
标量子查询几乎可以在查询中可以使用标量(即常量值)的任何地方使用。它们可以派上用场。它们并不完全等同于连接,因为:
- 一个
inner join
可以过滤值。标量子查询 returns NULL
如果没有返回行。
- 一个
join
可以乘以行数。标量子查询 returns 如果它 returns 超过一行则出错。
我对以下 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 |
+--------+------------------------------+
在现实生活中,我会说这两个查询只是避免连接的两种令人毛骨悚然的方法。
但在这种特殊情况下,它们包含在您找到的幻灯片中,以显示可以在多少地方使用嵌套循环。
他们都和下面的一样
SELECT name
FROM student s
JOIN enrolled e
ON s.sid = e.sid
WHERE cid = '15-445';
关于你的第一个查询的分步含义问题。就是下面
这将遍历“已注册”table 中 cid = '15-455' 的每条记录。
FROM enrolled as E WHERE cid='15-455';
对于第 1 步中的每条记录,它将执行以下查询
SELECT S.name FROM student AS S WHERE S.sid = E.sid;
如果你想获取如下信息:
学生姓名 |客户ID |年级 |
你可以这样做:
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
所以结果是一样的,但在第二个中你要避免连接。
这个结构:
SELECT (SELECT S.name FROM student S WHERE S.sid = E.sid) AS sname
-------^
称为 标量子查询 。这是一种特殊类型的子查询,具有两个重要属性:
- 是returns一栏。
- 最多returns一行。
在这种情况下,标量子查询也是一个相关子查询,这意味着它通过where
子句。
标量子查询几乎可以在查询中可以使用标量(即常量值)的任何地方使用。它们可以派上用场。它们并不完全等同于连接,因为:
- 一个
inner join
可以过滤值。标量子查询 returnsNULL
如果没有返回行。 - 一个
join
可以乘以行数。标量子查询 returns 如果它 returns 超过一行则出错。