SQL 中的嵌套查询

2025年3月17日 | 阅读 8 分钟

在嵌套查询中,一个查询在 SQL 中被实现为另一个查询的内部。内部查询的结果用于实现外部查询。在本查询中,我们将使用三个表来实现在 SQL 中理解嵌套查询:Student、Course 和 S_Course。

语法

创建子查询时应遵循以下规则列表

  • 嵌套查询必须用括号括起来。
  • 它不能包含 ORDER BY 子句。
  • 子查询的结果本身不显示,但会传递给父 SQL 语句供其使用。
  • BETWEEN 运算符不能与子查询一起使用。
  • 子查询必须要么只有一列,要么将其选择的列与主查询中括号内的多列进行比较。

学生

该表包含给定的信息

S_IDS_NAMES_ADDS_NoS_AGE
S1阿曼Noida892940319
S2拉格哈夫德里568703021
S3Harsh古尔冈402029518
S4哈希特Noida958392015

使用给定的查询创建给定的表

课程

该表包含给定的信息

C_IDCour_Name
C1英文
C2数学
C3科学

使用给定的插入查询创建上述表

S_Course

S_IDC_ID
S1C3
S1C2
S2C3
S3C3
S3C1
S4C2

使用此查询创建 S_Course 表

嵌套查询的类型

SQL 中可以实现两种类型的嵌套查询。它们如下

独立嵌套查询

在独立嵌套查询中,查询执行从最内部的查询开始,并移动到最外部的查询。内部查询的结果不受内部查询操作的影响。在内部查询中计算的结果作为参数用于外部查询。用于实现独立嵌套查询的几个操作包括 IN、NOT IN、ALL 和 ANY。

示例:考虑这样一种情况,您想获取希望注册 English 或 Maths 课程的学生 S_ID,我们可以使用独立嵌套查询和 IN 运算符来实现查询以检索上述信息。从 Course 表中,用户可以确定 English 或 Maths 课程的 C_ID,并使用相应的 C_ID 从 S_Course 表中查找 S_ID。

检索已注册 English 或 Maths 课程学生的 S_ID 的步骤。

步骤 1:首先找到相应课程的 C_ID。课程包括 Programming 和 DSA。执行给定的查询以检索上述结果。

步骤 2:一旦第一个查询被执行,它将从 Course 表中检索 C_ID,并使用 S_Course 表检索 S_ID。

输出

Nested Query In SQL

内部查询(即括号内的查询)将返回相应的 C_ID,在上述情况下为 C1 或 C2,外部查询将使用检索到的 C_ID 来检索 S_ID。查询将使用 S_Course 表来检索结果。这里 S1、S3 和 S4 符合条件。

用户还可以检索注册了 English 和 Maths 课程的学生姓名。这可以通过使用两个嵌套查询来检索。查询如下

输出

Nested Query In SQL

NOT IN:如果用户希望检索除注册了 English 或 Maths 的学生之外的所有学生的 S_ID。那么下面的查询将返回结果

输出

Nested Query In SQL

在这里您可以看到有两个内部查询。最内部的查询将返回 English 和 Maths 课程的 C_ID,即 C1 和 C2。然后第二个内部查询将检索注册了上述课程的所有学生的 S_ID,最后最外部的查询将检索除上一个语句中检索到的 S_ID 之外的所有 S_ID。在这种情况下,它是 S2。

关联嵌套查询

在这种类型的查询中,从内部查询检索到的结果取决于在外部查询中实现的行。当子查询为被主查询考虑的每一行返回不同的结果或结果集时,它就被使用。在关联查询中,我们首先从外部查询中获取一行,然后使用该行的值执行内部查询。该行是否符合条件取决于内部查询。这个过程会持续评估,直到所有满足外部查询条件的行都被考虑。

例如:如果用户希望获取注册了 C_ID=3 的学生姓名,那么用户可以执行关联查询以获取所需结果。查询如下

输出

Nested Query In SQL

上述查询将针对 Student S 的每个记录执行,它将查找所有满足条件 S.S_ID = SC.S_ID 和 SC.C_ID=3 的记录。如果对于 Student S 中的某个 S_ID,S_Course SC 中至少存在一条 C_ID=3 的记录,那么内部查询将变为真,并返回相应的 S_ID。

Exists 运算符

Exists 运算符在您对子查询返回的列值不感兴趣的情况下很有用。它通常与关联查询一起使用,以确定外部查询检索到的值是否存在于内部查询检索到的值的结果集中。如果子查询返回至少一行,则此运算符返回 TRUE;如果子查询不返回任何行,则返回 FALSE。

Exists 运算符使用以下语法

例如:要检索所有有员工的部门,请使用以下查询。

在子查询中使用组函数、Having 子句和 Distinct 子句

您也可以在子查询中使用聚合函数,因为它也产生单个结果。

例如:从 Student 表中检索年龄大于学生最小年龄的学生的 S_ID、S_NAME、S_AGE。

输出

S_IDS_NAMES_AGE
S1阿曼19
S2拉格哈夫21
S3Harsh18

此示例的输出如上所示。

考虑一个例子,假设我们想从 Student 表中检索年龄大于学生最大年龄的学生的 S_ID、S_NAME、S_AGE。

以下是这个例子的输出。

输出

S_IDS_NAMES_AGE
S2拉格哈夫21
S6Ravi25

我们还可以在子查询中使用 DISTINCT 子句。以下示例用于 DISTINCT 子句。

例如:列出居住在 Noida 市的所有学生 ID、学生姓名和电话号码。

以下是这个例子的输出。

输出

S_IDS_NAMES_ADDS_No
S1阿曼Noida8929403
S4哈希特Noida9583920

测试单个值的逻辑运算符可以与子查询一起使用,就像它们返回单个行一样。如果子查询返回多行,您将收到错误消息。考虑下面显示的示例以进一步解释这一点。

在上面的例子中,它会产生一个错误。这是因为内部查询的结果是 20、30、10。WHERE 子句包含一个相等运算符,这是一个单行比较,只期望一个值。因此,当从子查询接收到多个值时,它会生成一个错误消息。

多行子查询

返回多行的子查询称为多行子查询。以下操作用于多行子查询。

  • IN 运算符
  • ANY 运算符
  • ALL 运算符

IN 运算符:此运算符将一个值与子查询返回的每个值进行比较。

例如:列出居住在 Noida 市的所有学生 ID、学生姓名和电话号码。

输出

S_IDS_NAMES_ADDS_No
S1阿曼Noida8929403
S4哈希特Noida9583920

执行后,结果如上所示。

ANY 运算符:此运算符将一个值与子查询返回的每个值进行比较。如果子查询选择至少一行,则返回 TRUE;如果查询不返回任何行,则返回 FALSE。它必须位于 =、!=、>、<、>=、<= 之前。

ALL 运算符:此运算符将一个值与查询返回的每个值进行比较。如果子查询选择的所有行都满足比较,则评估为 TRUE。此外,如果子查询不产生任何行或值,则条件评估为 TRUE。所有运算符必须位于 =、!=、>、<、>=、<= 之前。

多列子查询

如果需要比较多列(即两列或更多列),那么我们使用包含逻辑运算符的复合 WHERE 子句。它从子查询返回多列。因此,允许用户将重复的 WHERE 条件组合成单个 WHERE 子句。

嵌套查询 MCQ

1. 在以下运算符列表中,哪个不能与子查询一起使用?

  1. IN
  2. ALL
  3. BETWEEN
  4. ANY

答案:c

解释: BETWEEN 运算符不能与子查询一起使用。

2. 在以下子句列表中,哪个不能在子查询中使用?

  1. DISTINCT
  2. ORDER BY
  3. FROM
  4. HAVING

答案:b

解释: ORDER BY 子句不能与子查询一起使用。

3. 以下嵌套查询的输出是什么?

Student 表包含给定的信息

S_IDS_NAMES_ADDS_NoS_AGE
S1阿曼Noida892940319
S2拉格哈夫德里568703021
S3Harsh古尔冈402029518
S4哈希特Noida958392015
  1. 15
  2. 21
  3. 19
  4. 16

答案:b

解释:  上面返回的学生最大年龄是 21。

4. 在以下查询列表中,哪个在语法上是正确的?

找出高于平均工资的员工的工资。

  1. Select salary from emp_table where salary (Select AVG(salary) from emp_table);
  2. Select from emp_table where salary > (Select AVG(salary) from emp_table);
  3. Select salary from emp_table where salary > (Select AVG(salary) from emp_table)
  4. Select salary from emp_table where salary > (Select AVG(salary) from emp_table);

答案:d

解释: 以下查询用于查找高于平均工资的员工的工资。

Select salary from emp_table where salary > (Select AVG(salary) from emp_table);


下一主题SQL Join 示例