第十五章 ACCESS SQL子查询
在SQL语言中,一个Select-FROM-Where语句称为一个查询块。当获得一个查询的答案需要多个步骤的操作,首先必须创建一个查询来确定用户不知道但包含在数据库中的值,将一个查询块嵌套在另一个查询块的Where字句或HAVING短语的条件中查询块称为子查询或内层查询。上层的查询块曾为父查询或外层查询。子查询的结果作为输入传递回“父查询”或“外部查询”。父查询将这个值结合到计算中,以便确定最后的输出。
SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。以层层嵌套的方式来构造程序正是SQL中“结构化”的含义所在。
子查询本质上就是一个完整的Select语句,它可以使一个Select、Select...INTO语句、Insert...INTO语句、Delete语句、或Update语句或嵌套在另一子查询中。子查询的输出可以包括一个单独的值(单行子查询)、几行值(多行子查询)、或者多列数据(多列子查询)。
第一节 ACCESS SQL子查询的完整语法
子查询是嵌套于Select、Select...INTO、Insert...INTO、Delete或Update语句内部或嵌套于另一个子查询内部的Select语句。下面我们先来学习一下ACCESS SQL子查询的完整的语法如下。
一、ACCESS SQL子查询的完整语法
可以使用三种格式的语法来创建子查询:
comparison [ANY | ALL |
SOME] (sqlstatement)
expression [NOT] IN (sqlstatement)
[NOT] EXISTS (sqlstatement)
子查询包含以下部分:
部分
|
描述
|
comparison
|
表达式和用于将该表达式与子查询的结果进行比较的比较运算符。
|
expression
|
将在其中搜索子查询结果集的表达式。
|
sqlstatement
|
Select语句,遵循与其他任何Select语句相同的格式和规则。它必须括在圆括号中。
|
二、关于子查询的几点注解说明
在Select语句的字段列表中或在Where或HAVING子句中可以使用子查询而不是表达式。在子查询中,可以使用Select语句来提供一个或一组特定值以计算Where或HAVING子句表达式。
使用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子句中列出的表。以下示例返回其薪金等于或大于相同工作职务的所有雇员平均薪金的雇员的姓名。“雇员 (Employees)”表的别名设定为“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列表中)。
三、子查询在VBA编程中应用示例
以下示例列出在1995年第二季度下过订单的每个客户的名称和联系人。
以下示例调用EnumFields过程,您可以在Select语句示例中找到该过程。
Sub SubQueryX()
Dim dbs As Database, rst As Recordset
' Modify this line to include the path to
Northwind
' on your computer.
Set dbs = OpenDatabase("Northwind.mdb")
' List the name and contact of every
customer
' who placed an order in the second quarter
of
' 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#);")
' Populate the Recordset.
rst.MoveLast
' Call EnumFields to print the contents of
the
' Recordset. Pass the Recordset object and
desired
' field width.
EnumFields rst, 25
dbs.Close
End Sub