有时,你可能希望将查询结果用作另一个查询中的字段,或用作查询字段的标准。 例如,假设你要查看每个产品的订单之间的间隔。 若要创建显示此间隔的查询,需要将每个订单日期与该产品的其他订单日期进行比较。 比较这些订单日期还需要查询。 可以使用函数将此查询嵌套在主查询 子查询 。
可以在 表达式 或 SQL 视图 中的 结构化查询语言 (SQL) 语句中编写子#x1。
本文内容
将查询结果用作另一个查询中的字段
可以使用子查询作为字段别名。 若要在主查询中将子查询结果用作字段,请使用子查询作为字段别名。
注意: 用作字段别名的子查询不能返回多个字段。
可以使用子查询字段别名显示依赖于当前行中其他值的值,如果不使用子查询,则不能显示这些值。
例如,让我们返回到想要查看每个产品的订单间隔的示例。 若要确定此间隔,需要将每个订单日期与该产品的其他订单日期进行比较。 可以使用 Northwind 数据库模板创建显示此信息的查询。
-
在“文件”选项卡上,单击“新建”。
-
在"可用模板"下,单击"示例模板"。
-
单击Northwind,然后单击"创建"。
-
按照“罗斯文贸易”页(在“启动屏幕”对象选项卡上)上的说明打开数据库,然后关闭“登录对话框”窗口。
-
在“创建”选项卡上的“查询”组中,单击“查询设计”。
-
单击"查询"选项卡,然后双击"产品订单"。
-
双击"产品 ID" 字段和" 订单日期 "字段,将其添加到查询设计网格。
-
在网格的"产品ID"列的"排序"行中,选择"升序"。
-
在网格的"订单日期"列的"排序"行中,选择"降序"。
-
在网格的第三列中,右键单击"字段"行,然后单击快捷菜单上的"缩放"。
-
在" 缩放 "对话框中,键入或粘贴以下表达式:
Prior Date: (SELECT MAX([Order Date])
FROM [Product Orders] AS [Old Orders]
WHERE [Old Orders].[Order Date] < [Product Orders].[Order Date]
AND [Old Orders].[Product ID] = [Product Orders].[Product ID])此表达式是子查询。 对于每个行,子查询选择比已与该行关联的订单日期最近的订单日期。 请注意如何使用 AS 关键字创建表别名,以便可以将子查询中的值与主查询当前行中的值进行比较。
-
在网格的第四列中的" 字段 "行中,键入以下表达式:
Interval: [Order Date]-[Prior Date]
此表达式使用使用子查询定义的前一日期的值来计算该产品的每个订单日期和前一个订单日期之间的间隔。
-
在“设计”选项卡上的“结果”组中,单击“运行”。
-
查询将运行并显示产品名称、订单日期、以前的订单日期以及订单日期之间的间隔列表。 结果首先按产品 ID (按升序) 排序,然后按订单日期 (降序) 。
-
注意: 由于产品 ID 是一个查找字段,因此默认情况下,Access 将显示查找值 (,在这种情况下,产品名称) 而不是实际产品 ID。 尽管这会更改显示的值,但它不会更改排序顺序。
-
-
关闭 Northwind 数据库。
将子查询用作查询字段的标准
可以使用子查询作为字段条件。 若要使用子查询的结果来限制字段显示的值,请使用子查询作为字段条件。
例如,假设你要查看由非销售代表的员工 处理的订单列表 。 若要生成此列表,需要将每个订单的员工 ID 与非销售代表的员工的员工 ID 列表进行比较。 若要创建此列表并用作字段条件,请使用子查询,如以下过程所示:
-
打开 Northwind.accdb 并启用其内容。
-
关闭登录窗体。
-
在“创建”选项卡上的“其他”组中,单击“查询设计”。
-
在"表"选项卡上,双击"订单"和"员工"。
-
在"订单"表中,双击"员工 ID" 字段、"订单 ID" 字段和"订单 日期 "字段,将其添加到查询设计网格。 在"员工"表中,双击"职务" 字段 以将其添加到设计网格。
-
右键单击" 员工 ID"列的"条件"行,然后单击 快捷菜单上的 "缩放"。
-
在 "缩放 "框中,键入或粘贴以下表达式:
IN (SELECT [ID] FROM [Employees]
WHERE [Job Title]<>'Sales Representative')这是子查询。 它选择该员工没有销售代表职务的所有员工 ID,并结果集主要查询。 然后,主查询会检查"订单"表中的员工结果集。
-
在“设计”选项卡上的“结果”组中,单击“运行”。
查询运行,查询结果显示由非销售代表的员工处理的订单列表。
可用于SQL查询的常见关键字
可通过SQL查询使用多个关键字:
注意: 此列表并不详尽。 可以在子查询中使用SQL有效关键字,但不包括数据定义关键字。
-
ALL 与子查询返回的每一行相比,使用 WHERE 子句中的 ALL 检索满足条件的行。
例如,假设你正在分析大学的学生数据。 学生必须维护最低 GPA,该 GPA 因专业而异。 专业及其最低 GBA 存储在一个名为"专业"的表中,相关学生信息存储在名为 Student_Records。
若要查看每个具有该专业的学生 (其最低 GPA) 其最低 GPA 的列表,可以使用以下查询:
SELECT [Major], [Min_GPA]
FROM [Majors]
WHERE [Min_GPA] < ALL
(SELECT [GPA] FROM [Student_Records]
WHERE [Student_Records].[Major]=[Majors].[Major]); -
ANY 与子查询返回的至少一行相比,使用 WHERE 子句中的 ANY 检索满足条件的行。
例如,假设你正在分析大学的学生数据。 学生必须维护最低 GPA,该 GPA 因专业而异。 专业及其最低 GBA 存储在一个名为"专业"的表中,相关学生信息存储在名为 Student_Records。
若要查看具有该专业 (学生不满足最低 GPA) 的 GPU 及其最低 GPA 列表,可以使用以下查询:
SELECT [Major], [Min_GPA]
FROM [Majors]
WHERE [Min_GPA] > ANY
(SELECT [GPA] FROM [Student_Records]
WHERE [Student_Records].[Major]=[Majors].[Major]);注意: 也可以将 SOME 关键字用于同一目的;SOME 关键字与 ANY 同义。
-
EXISTS 在 WHERE 子句中使用 EXISTS 来指示子查询应返回至少一行。 也可以以 NOT 作为 EXISTS 的前言,以指示子查询不应返回任何行。
例如,以下查询返回至少以一个现有订单找到的产品列表:
SELECT *
FROM [Products]
WHERE EXISTS
(SELECT * FROM [Order Details]
WHERE [Order Details].[Product ID]=[Products].[ID]);使用 NOT EXISTS 时,查询返回至少一个现有订单中找不到的产品列表:
SELECT *
FROM [Products]
WHERE NOT EXISTS
(SELECT * FROM [Order Details]
WHERE [Order Details].[Product ID]=[Products].[ID]); -
IN 在 WHERE 子句中使用 IN 来验证主查询的当前行中的值是否属于子查询返回的集。 还可以以 IN 为前言,使用 NOT 来验证主查询的当前行中的值是否不是子查询返回的集的一部分。
例如,以下查询返回订单列表, (不是销售代表) 处理的订单日期:
SELECT [Order ID], [Order Date]
FROM [Orders]
WHERE [Employee ID] IN
(SELECT [ID] FROM [Employees]
WHERE [Job Title]<>'Sales Representative');通过使用 NOT IN,可以按以下方式编写相同的查询:
SELECT [Order ID], [Order Date]
FROM [Orders]
WHERE [Employee ID] NOT IN
(SELECT [ID] FROM [Employees]
WHERE [Job Title]='Sales Representative');