此示例选择在员工表中的所有记录,然后复制到命名为 Emp Backup 的新表中。
Sub SelectIntoX()
Dim dbs As Database
Dim qdf As QueryDef
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 选择员工表中的所有记录,
' 并且复制到称作员工备份的新表中。
dbs.Execute "SELECT Employees.* INTO " _
& "[Emp Backup] FROM Employees;"
' 删除 QueryDef 因为这是一个演示。
dbs.Execute "DROP TABLE [Emp Backup];"
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INSERT INTO 语句
添加一个或多个记录至一个表。这叫作追加查询.
语法
多重记录追加查询:
INSERT INTO target [(field1[, field2[, ...]])][IN外部数据库]
SELECT field1[, field2[, ...]]
FROM tableexpression
单一记录追加查询:
INSERT INTO target [(field1[, field2[, ...]])]
VALUES (value1[, value2[, ...])
INSERT INTO 语句可分为以下几个部分:
部分 | 说明 |
---|---|
target | 欲追加记录的表或查询的名称。 |
field1, field2 | 如果后面跟的是 target 参数,则为要追加数据的字段名;如果后面跟的是 source 参数,则为从其中获得数据的字段名。 |
Externaldatabase | 进入外部数据库的路径。有关路径的描述,请参阅 IN 子句。 |
source | 复制记录的来源表或查询的名称。 |
tableexpression | 从其中得到要插入的记录的表名。这个变元可能是一个单一的表名,也可能是一个由 INNER JOIN, LEFT JOIN或 RIGHT JOIN 运算组成的复合体,或是一个储存的查询。 |
value1,value2 | 欲插入新记录的特定字段的值。每一个值将依照它在列表中的位置,顺序插入相关字段:value1 将被插入至追加记录的 field1 之中,value2 插入至 field2,依此类推。必须使用逗点将这些值分隔,并且将文本字段用引号 (' ') 括起来。 |
说明
可以使用 INSERT INTO 语句来添加一个单一记录至一个表中,如以上所示使用单一记录追加查询语法。在这个例子中,代码指定了该记录每一字段的名称和值。必须指定追加数值的记录的每一个字段和那个字段的值。如果您没有指定每一个字段时,缺省值或 Null 值将被插入至没有数据的字段之中。这些记录将被添加至表的尾部。
通过使用 SELECT ...FROM 子句如以上所示的多重记录追加查询语法,也可以从另一表或查询使用 INSERT INTO追加一组记录。在这个示例中,SELECT 子句将指定追加字段至指定的 target 表。
source 或 target 表可以指定一个表或查询。如果查询被指定,Microsoft Jet数据库引擎会把记录追加到由该查询指定的所有表中。
INSERT INTO 是可选的,但当使用时,请置於 SELECT 语句之前。
如果你的目标表包含一个 主键,,你一定要把唯一的非 Null 值追加到主键字段中,否则 Microsoft Jet 数据库引擎不会追加记录。
如果你要把把记录追加到带有 AutoNumber字段的表中,还想重编追加的记录,请不要在你的查询中包含 AutoNumber字段。如果您要保持字段中的原始值,请将自动编号加在您的查询之中。
使用 IN 子句,可追加记录至另一个数据库中的表。
要创建新表请用 SELECT...INTO 语句代替制表查询的创建。
若要在运行追加查询之前找出哪些记录是被追加的,首先执行和查阅一个使用相同的选择条件之选定查询所获得的结果。
追加查询为从一个或多个表中复制记录至另一个表。您追加的表包含记录将不会被追加查询所影响。
除了从另一表中来追加现存的记录,可以指定在单一追加记录之中使用 VALUES 子句来指定对每一字段的值。如果您省略字段列表,VALUES 子句在表之中必须包含每一字段的值;否则, INSERT运算将会失败。使用额外的 INSERT INTO 语句与一个 VALUES 子句来创建您要的每一个额外的记录。
请参阅
示例
此示例选择在一假设的新客户表中的所有记录,并且增加它们至客户表中。当个别的栏没有设计时,此 SELECT 表的列名必须完全地符合那些在 INSERT INTO 表中的列名。
Sub InsertIntoX1()
Dim dbs As Database
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 在新客户表中选择所有记录,
' 并且添加它们至客户表。
dbs.Execute " INSERT INTO Customers " _
& "SELECT * " _
& "FROM [New Customers];"
dbs.Close
End Sub
此示例创建在员工表中的添加记录。
Sub InsertIntoX2()
Dim dbs As Database
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 创建在员工表中的新记录,
' 其姓氏是 Washington,名字是 Harry,
' 并且职称是 Trainee。
dbs.Execute " INSERT INTO Employees " _
& "(FirstName,LastName, Title) VALUES " _
& "('Harry', 'Washington', 'Trainee');"
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
UPDATE 语句
创建更新查询来改变基于特定准则的指定表中的字段值。
语法
UPDATE 表
SET新值
WHERE准则;
UPDATE 语句可分为以下几个部分:
部分 | 说明 |
---|---|
table | 表的名称,其中包含要更改的数据。 |
newvalue | 表达式,用来计算要插入更新记录中特定字段的值。 |
criteria | 表达式,用来计算被更新的记录。只有符合表达式的记录才会被更新。 |
说明
当需要更改多个记录,或要更改的记录在多重表中时,UPDATE 特别有用。
可以同时更改多个字段。下列示例为对联合王国的一家公司增加 10% 的 Order Amount (订货量)和 3% 的 Freight (货运):
UPDATE Orders
SET OrderAmount = OrderAmount * 1.1,
Freight = Freight * 1.03
WHERE ShipCountry = 'UK';
重点
- UPDATE 不生成结果集。而且当使用更新查询更新记录之后,不能取消这次操作。如果想知道哪些记录被更新,先看一下使用相同的条件的选定查询的结果,然后运行更新查询。
- 随时注意维护数据的复制备份。如果更新了错误记录,可从备份副本中恢复这些数据。
请参阅
SELECT 语句 (Microsoft Jet SQL) | WHERE 子句 (Microsoft Jet SQL) |
示例
此示例对于所有当前的“ReportsTo”字段值为 2 的员工记录更改其“ReportsTo”字段值为 5。
Sub UpdateX()
Dim dbs As Database
Dim qdf As QueryDef
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 对于当前所有 ReportsTo 字段值为 2 的员工记录
' 把其ReportsTo字段值改为5。
'
dbs.Execute "UPDATE Employees " _
& "SET ReportsTo = 5 " _
& "WHERE ReportsTo = 2;"
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DELETE 语句
创建一个删除查询把记录从 FROM 子句列出并符合 WHERE 子句的一个或更多的表中清除。
语法
DELETE [表.*]
FROM 表
WHERE标准
DELETE 语句可分为以下几个部分:
部分 | 说明 |
---|---|
table | 从其中删除记录的表的可选名称。 |
table | 从其中删除记录的表的名称。 |
criteria | 确定删除哪个记录的表达式。 |
说明
可以使用 DELETE 删除多个记录。
可以用 Execute 方法和 DROP 语句从数据库中删除整个表。不过,若用这种方法删除表,将会失去表的结构。不同的是当使用 DELETE,只有数据会被删除;表的结构以及表的所有属性仍然保留,例如字段属性及索引。
可以用 DELETE从与其他表有着 一对多关系的表中清除记录。若在一个查询中删除了关系中‘一’的一方的表的相应记录,级联删除操作将删除关系中‘多’的一方的表的记录。例如,在客户表与订单表之间的关系中,客户表是‘一’方,而订单表是‘多’方。如果指定使用级联删除,从客户数据中删除一个记录,相对应之订单记录也会被删除。
删除查询不只删除指定字段之中的数据,它会删除全部的记录。如果要删除指定字段值,可创建更新查询使该值变为 Null.
重点
- 当使用删除查询删除记录之后,不能取消此操作。如果想要知道哪些记录已被删除,首先验证使用相同条件的选定查询的结果,然后运行删除查询。
- 随时注意维护数据的复制备份。如果您误删除记录,可以从备份副本中将数据恢复。
请参阅
DROP 语句 (Microsoft Jet SQL) | SELECT 语句 (Microsoft Jet SQL) |
FROM 子句 (Microsoft Jet SQL) | UPDATE 语句 (Microsoft Jet SQL) |
IN 子句(Microsoft Jet SQL) | WHERE 语句 (Microsoft Jet SQL) |
INNER JOIN 运算 (Microsoft Jet SQL) |
示例
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
EXECUTE 语句
用于激活 PROCEDURE.
语法
EXECUTE过程 [参数1[, 参数2[, ...]]
UPDATE 语句可分为以下几个部分:
部分 | 说明 |
---|---|
过程 | 要执行的过程名 |
param1, param2 | 由该过程定义的参数s值 |
请参阅
PARAMETERS 声明 (Microsoft Jet SQL) | PROCEDURE 子句 (Microsoft Jet SQL) |
示例
CREATE PROCEDURE 语句, PROCEDURE 子句示例
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INNER JOIN 运算
组合两个表中的记录,只要在公共字段之中有相符的值。
语法
FROM table1 INNER JOIN table2 ON table1.field1 compopr table2.field2
INNER JOIN 运算可分为以下几个部分:
部分 | 说明 |
---|---|
table1, table2 | 记录被组合的表的名称。 |
field1, field2 | 被联接的字段的名称。若它们不是由数字构成的,则这些字段必须为相同的数据类型并包含同类数据,但它们无须具有相同的名称。 |
compopr | 任何的关系比较运算子:"=," "<," ">," "<=," ">=," 或 "<>." |
说明
可以在 FROM 子句中使用INNER JOIN运算。.这是最普通的联接类型。只要在这两个表的公共字段之中有相符值,内部联接将组合两个表中的记录。
可以使用 INNER JOIN 与部门表及员工表选择每一个部门中的全部员工。反之,可以使用 LEFT JOIN或 RIGHT JOIN运算创建 outer join,从而选择所有部门(即使有些并没有员工)或所有员工(即使有些尚未分配到部门)。
若试图联接包含 Memo或 OLE Object数据的字段,会导致错误。
可以联接任何两个相同类型的数值字段。例如,可以联接 AutoNumber和 Long字段,因为它们类型相似。但不能联接 Single 和 Double 类型的字段。
下列示例显示如何在类标识符字段联接类表及产品表:
SELECT CategoryName, ProductName
FROM Categories INNER JOIN Products
ON Categories.CategoryID = Products.CategoryID;
在上面的示例中,类标识符是已被联接的字段,但是它并不包含在查询输出中,因它并非被包含在 SELECT 语句之中。在这个示例中,若要包含联接字段,将字段名包含在 SELECT 语句中, Categories.CategoryID.
也可以使用下列语法,在一个 JOIN 语句中链接多个 ON 子句:
SELECT fields
FROM table1 INNER JOIN table2
ON table1.field1 compopr table2.field1 AND
ON table1.field2 compopr table2.field2) OR
ON table1.field3 compopr table2.field3)];
也可以使用下列语法,嵌套 JOIN 语句:
SELECT fields
FROM table1 INNER JOIN
(table2 INNER JOIN [( ]table3
[INNER JOIN [( ]tablex [INNER JOIN ...)]
ON table3.field3 compopr tablex.fieldx)]
ON table2.field2 compopr table3.field3)
ON table1.field1 compopr table2.field2;
在一个 INNER JOIN 之中,可以嵌套 LEFT JOIN 或 RIGHT JOIN,但是在 LEFT JOIN 或 RIGHT JOIN 中不能嵌套 INNER JOIN。
请参阅
FROM 子句 (Microsoft Jet SQL) | TRANSFORM 语句 (Microsoft Jet SQL) |
LEFT JOIN, RIGHT JOIN 运算 (Microsoft Jet SQL) | UNION 运算 (Microsoft Jet SQL) |
SELECT 语句 (Microsoft Jet SQL) |
示例
此示例创建了两个对等联接:一个是在订货明细表和订单表之间,另一个是在订单表和员工表之间。这是必需的,因为员工表不含业务人员数据,并且订货明细表不含员工数据。查询生成员工和他们的业绩列表。
此示例调用过程 EnumFields 过程,且可以在 SELECT 语句示例中找到该过程。
Sub InnerJoinX()
Dim dbs As Database, rst As Recordset
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 在订单明细和订单表之间创建联接
'
' 并且在订单和员工表之间创建联接。列出员工和他们的业绩
'
Set rst = dbs.OpenRecordset("SELECT DISTINCTROW " _
& "Sum(UnitPrice * Quantity) AS Sales, " _
& "(FirstName & Chr(32) & LastName) AS Name " _
& "FROM Employees INNER JOIN(Orders " _
& "INNER JOIN [Order Details] " _
& "ON [Order Details].OrderID = " _
& "Orders.OrderID ) " _
& "ON Orders.EmployeeID = " _
& "Employees.EmployeeID " _
& "GROUP BY (FirstName & Chr(32) & LastName);")
' populateRecordset。
rst.MoveLast
' 调用 EnumFields 来打印记录集的内容。
'传递记录集对象和要求的字符宽度。
'
EnumFields rst, 20
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
LEFT JOIN 和 RIGHT JOIN 运算
用于 FROM 子句时,把源表记录组合起来。
语法
FROM表1 [ LEFT | RIGHT ] JOIN表2
ON 表1.字段1 compopr 表2. 字段2
LEFT JOIN 及 RIGHT JOIN 运算可分为以下几个部分:
部分 | 说明 |
---|---|
table1, table2 | 记录被组合的表的名称。 |
field1, field2 | 被联接的字段的名称。且这些字段必须有相同的数据类型及包含相同类型的数据,但它们不需要有相同的名称。 |
compopr | 任何的关系比较运算子:"=," "<," ">," "<=," ">=," 或 "<>." |
说明
用 LEFT JOIN 运算 创建左边外部联接.左边外部联接将包含了从第一个(左边)开始的两个表中的全部记录,即使在第二个(右边)表中并没有相符值的记录。
用RIGHT JOIN 运算 创建 右边外部联接.右边外部联接将包含了从第二个(右边)开始的两个表中的全部记录,即使在第一个(左边)表中并没有匹配值的记录。
例如,可以使用 LEFT JOIN 与部门(左边)及员工(右边)表来选择所有的部门,包含了没有分配到员工的部门。可以使用 RIGHT JOIN 选择所有的员工,包含了没有分配到部门的员工。
下列示例显示如何在类标识符字段中联接类表及产品表。查询将会列出所有种类的列表,包含那些没有产品在其中的种类:
SELECT CategoryName,
ProductName
FROM Categories LEFT JOIN Products
ON Categories.CategoryID = Products.CategoryID;
在本例中,CategoryID 是联接的字段,但由于它不包含在 SELECT 语句中,因此,也不包含在查询结果中。要包含联接的字段,请在 SELECT 语句中输入字段名 — 在这个示例中为 Categories.CategoryID。
注意
欲创建只包含联接字段中数据相同的记录的查询,请用 INNER JOIN 运算。
- 在 INNER JOIN 之中可以写一个嵌套的 LEFT JOIN 或一个 RIGHT JOIN,但是在一个 LEFT JOIN 或一个 RIGHT JOIN 之中不能写嵌套的 INNER JOIN。请参阅 INNER JOIN 主题中有关使用嵌套的讨论,从其中可获知如何在其它联接中编写嵌套联接的信息。
- 可以链接多个 ON 子句。若需更多信息,请参阅在 INNER JOIN 主题中的子句链接的讨论。
若试图联接包含 Memo或 OLE Object数据的字段,会导致错误。
请参阅
FROM 子句 (Microsoft Jet SQL) | UNION 运算 (Microsoft Jet SQL) |
INNER JOIN 运算 (Microsoft Jet SQL) |
示例
此示例假设在员工表中存在假设的单位名称和单位标识符的字段。注意这些字段实际上在 Northwind 数据库员工表中并不存在。
此示例选择所有单位,包含那些不含员工的单位。
此示例调用过程 EnumFields 过程,且可以在 SELECT 语句示例中找到该过程。
Sub LeftRightJoinX()
Dim dbs As Database, rst As Recordset
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 选取所有单位,包括
' 没有员工的
Set rst = dbs.OpenRecordset _
("SELECT [Department Name], " _
& "FirstName & Chr(32) & LastName AS Name " _
& "FROM Departments LEFT JOIN Employees " _
& "ON Departments.[Department ID] = " _
& "Employees.[Department ID] " _
& "ORDER BY [Department Name];")
' populateRecordset。
rst.MoveLast
' 调用 EnumFields 来打印记录集的内容。
'传递记录集对象和要求的字符宽度。
'
EnumFields rst, 20
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
UNION 运算
创建一个联合查询,它组合了两个或更多的独立查询或表的结果。
语法
[TABLE] query1 UNION [ALL] [TABLE] query2 [UNION [ALL] [TABLE] queryn [ ... ]]
UNION 运算可分为以下几个部分:
部分 | 说明 |
---|---|
query1-n | SELECT 语句、已存储的查询的名称、或冠以 TABLE 关键字的存储表的名称。 |
说明
可以在任何组合中、单一 UNION 运算中,合并两个或多个查询、表、及 SELECT 语句的结果。下列示例将名为 New Accounts 的现存表和一个 SELECT 语句合并:
TABLE [New Accounts] UNION ALL
SELECT *
FROM Customers
WHERE OrderAmount > 1000;
按照缺省规定,使用 UNION 运算时不返回重复的记录;然而,可以包含 ALL 谓词来确保返回所有的记录。这样,运行查询的速度也会快些。
一次 UNION 运算中的所有查询必须要求相同的字段数量;但是,字段无须具有相同的大小或数据类型。
只能在第一个 SELECT 语句中使用别名,因为它们在其他语句中已被省略。在 ORDER BY 子句中,可引用在第一个 SELECT 语句中被调用的字段名。
注意
- 可以在各个查询变元中使用GROUP BY或 HAVING 子句来为返回的数据分组。
- 要想以指定的顺序来显示返回的数据,可以在最后一个 query 参数的末尾使用 ORDER BY 子句。
请参阅
示例
此示例捕获在巴西的所有供给商和客户的名字及城市。
此示例调用过程 EnumFields 过程,且可以在 SELECT 语句示例中找到该过程。
Sub UnionX()
Dim dbs As Database, rst As Recordset
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 捕获在巴西的所有供给商和客户的名字及城市。
'
Set rst = dbs.OpenRecordset("SELECT CompanyName," _
& " City FROM Suppliers" _
& " WHERE Country = 'Brazil' UNION" _
& " SELECT CompanyName, City FROM Customers" _
& " WHERE Country = 'Brazil';")
' populateRecordset。
rst.MoveLast
' 调用 EnumFields 来打印记录集的内容。
'传递记录集对象和要求的字符宽度。
'
EnumFields rst, 12
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
PROCEDURE 子句
给查询定义一个名称和可选参数s。
注意: PROCEDURE 子句 已被 PROCEDURE 语句取代。尽管PROCEDURE 子句仍受支持,但 PROCEDURE 语句会提供PROCEDURE 子句容量的超集,而且语句也是推荐语法。
语法
PROCEDURE name [param1 datatype[, param2 datatype[, ...]]
PROCEDURE 子句可分为以下几个部分:
部分 | 说明 |
---|---|
name | 过程的名称。它应遵循标准命名公约。 |
param1, param2 | 一个或更多的字段名或参数。例如: PROCEDURE Sales_By_Country [Beginning Date] DateTime, [Ending Date] DateTime; 欲知更多参数信息,请看参数. |
datatype | 基本 Microsoft Jet SQL数据类型或其同义字之一。 |
说明
由 PROCEDURE 子句(指定过程名称的)、可选的参数定义列表和单个 SQL 语句组成的 SQL 过程。例如,过程 Get_Part_Number 可以运行一个检索指定部分的号码的查询。
注意
请参阅
DELETE 语句 (Microsoft Jet SQL) | PARAMETERS 声明 (Microsoft Jet SQL) |
EXECUTE 语句 (Microsoft Jet SQL) | SELECT 语句 (Microsoft Jet SQL) |
Microsoft Jet 数据库引擎 SQL 的数据类型 | UPDATE 语句 (Microsoft Jet SQL) |
示例
CREATE TABLE 语句,CONSTRAINT 子句示例
此示例命名查询为 CategoryList。
此示例调用过程 EnumFields 过程,且可以在 SELECT 语句示例中找到该过程。
Sub ProcedureX()
Dim dbs As Database, rst As Recordset
Dim qdf As QueryDef, strSql As String
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
strSql = "PROCEDURE CategoryList; " _
& "SELECT DISTINCTROW CategoryName, " _
& "CategoryID FROM Categories " _
& "ORDER BY CategoryName;"
' 创建基于 SQL 语句的 QueryDef 的名称。
'
Set qdf = dbs.CreateQueryDef("NewQry", strSql)
' 创建暂时的快照类型记录集。
Set rst = qdf.OpenRecordset(dbOpenSnapshot)
' populateRecordset。
rst.MoveLast
' 调用 EnumFields 来打印记录集的内容。
'传递记录集对象和要求的字符宽度。
'
EnumFields rst, 15
' 删除 QueryDef 因为这是一个演示。
'
dbs.QueryDefs.Delete "NewQry"
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SQL 子查询
子查询是一个 SELECT 语句,它嵌套在一个 SELECT、SELECT...INTO 语句、INSERT...INTO 语句、DELETE 语句、或 UPDATE 语句或嵌套在另一子查询中。
语法
可用三种语法来创建子查询:
comparison [ANY | ALL | SOME] (sqlstatement)
expression [NOT] IN (sqlstatement)
[NOT] EXISTS (sqlstatement)
子查询可分为以下几个部分:
部分 | 说明 |
---|---|
comparison | 一个表达式及一个比较运算符,将表达式与子查询的结果作比较。 |
expression | 用以搜寻子查询结果集的表达式。 |
sqlstatement | SELECT 语句,遵从与其他 SELECT 语句相同的格式及规则。它必须括在括号之中。 |
说明
可以拿子查询代替表达式 用于SELECT 语句字段表或 WHERE 或 HAVING 子句。在子查询之中,在 WHERE 或 HAVING 子句的表达式中,用于计算的特定值是由 SELECT 语句提供的。
使用 ANY 或 SOME 谓词,它们是同义字,来检索主查询中的记录,这些记录要满足在子查询中检索的任何记录的比较条件。下列示例将返回全部单价比任何以 25% 或更高的折扣卖出的产品高的产品:
SELECT * FROM Products
WHERE UnitPrice > ANY
(SELECT UnitPrice FROM OrderDetails
WHERE Discount >= .25);
使用 ALL 谓词只检索主查询中的这些记录,它们满足在子查询中检索的所有记录的比较条件。如果将前一个示例中的 ANY 改为 ALL,查询只会返回单价比全部以 25% 或更高的折扣卖出的产品高的产品。这是更多的限制。
用 IN 谓词,只能在主查询检索那些记录,在子查询中的某些记录也包含和它们相同的值。下列示例返回有 25% 或更高的折扣的所有产品:
SELECT * FROM Products
WHERE ProductID IN
(SELECT ProductID FROM OrderDetails
WHERE Discount >= .25);
相反,可用 NOT IN 在主查询中检索那样的记录,在子查询中没有包含与它们的值相同的记录。
在 true/false 比较中使用 EXISTS 谓词(与可选的 NOT 保留字一道)来决定子查询是否会返回任何记录。
还可用子查询中的表名别名来查询子查询外的 FROM 子句的列表。下列示例返回工资等于或高于所有职位相同员工的平均工资的员工姓名。这张员工表的别名为 "T1":
SELECT LastName,
FirstName, Title, Salary
FROM Employees AS T1
WHERE Salary >=
(SELECT Avg(Salary)
FROM Employees
WHERE T1.Title = Employees.Title) Order by Title;
上例中AS保留词可选。
某些子查询在交叉表查询中是允许的,特别是谓词(那些在 WHERE 子句中的)。将子查询作为输出(那些列在 SELECT 中的)在交叉表查询中是不允许的。
请参阅
示例
此示例列出每一客户的名称和 1995 第二季订单的联络人。
此示例调用过程 EnumFields 过程,且可以在 SELECT 语句示例中找到该过程。
Sub SubQueryX()
Dim dbs As Database, rst As Recordset
' 在您的计算机中修改此行使其正确指到 Northwind 的路径。
Set dbs = OpenDatabase("Northwind.mdb")
' 对运费超过 $100 的订单,
' 列出每一客户的名称和
' 1995 第二季中订单的联络人。
' 1995.
Set rst = dbs.OpenRecordset("SELECT ContactName," _
& " CompanyName, ContactTitle, Phone" _
& " FROM Customers" _
& " WHERE CustomerID" _
& " IN (SELECT CustomerID FROM Orders" _
& " WHERE OrderDate Between #04/1/95#" _
& " And #07/1/95#);")
' populateRecordset。
rst.MoveLast
' 调用 EnumFields 来打印记录集的内容。
'传递记录集对象和要求的字符宽度。
'
EnumFields rst, 25
dbs.Close
End Sub
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%