📄 access 2000中级篇_语法参考.htm
字号:
<p>IN子查询<br>
IN 子查询用于检索这样的一组值,即其中记录的某一列的值都为另一个工作表或查询中的一列的值包含。它从其它工作表中只能返回一列,这是一个限制条件。如果返回的多于一列就会产生一个错误。使用发票数据库例子,我们可以写出一个返回所有拥有发票的顾客的列表的SQL语句。</p>
<p>SELECT *<br>
FROM tblCustomers<br>
WHERE CustomerID<br>
IN (SELECT CustomerID FROM tblInvoices)<br>
</p>
<p>通过使用NOT逻辑操作符,我们可以检索和IN子查询相反的记录,从而可以获得所有没有任何发票的顾客列表。</p>
<p>SELECT *<br>
FROM tblCustomers<br>
WHERE CustomerID<br>
NOT IN (SELECT CustomerID FROM tblInvoices)<br>
</p>
<p>ANY/SOME/ALL子查询</p>
<p>ANY、 SOME和ALL子查询谓词被用于比较主查询的记录和子查询的多个输出记录。ANY 和 SOME谓词是同义词并可以被替换使用。</p>
<p>当你需要从主查询中检索任何符合在子查询中满足比较条件的记录时可以使用ANY或 SOME谓词。谓词应该恰好放在子查询开始的括号前面。</p>
<p>SELECT *<br>
FROM tblCustomers<br>
WHERE CustomerID = ANY<br>
(SELECT CustomerID FROM tblInvoices)<br>
</p>
<p>注意由上面SQL语句所返回的结果集和IN子查询例子所返回的那个相同。而与ANY和SOME谓词的不同之处就在于它们都可以使用等于(=)以外的操作符,比如大于(>)和小于(<)。</p>
<p>SELECT *<br>
FROM tblCustomers<br>
WHERE CustomerID > ANY<br>
(SELECT CustomerID FROM tblInvoices)<br>
</p>
<p>当我们想在主查询中检索满足子查询比较条件的所有记录时使用谓词ALL。</p>
<p>SELECT *<br>
FROM tblCustomers<br>
WHERE CustomerID > ALL<br>
(SELECT CustomerID FROM tblInvoices)<br>
</p>
<p>EXISTS子查询</p>
<p>EXISTS谓词是用于子查询来在一个结果集中检查所以存在值的记录。换句话说,就是如果子查询没有返回任何行,这个比较就False。而如果它返回了一行或多行,这个比较就为True。</p>
<p>SELECT *<br>
FROM tblCustomers AS A<br>
WHERE EXISTS<br>
(SELECT * FROM tblInvoices<br>
WHERE A.CustomerID = tblInvoices.CustomerID)<br>
</p>
<p>注意在前面的SQL 语句里, tblCustomers 工作表使用了一个别名。这就是为何我们可以在后来的子查询中引用它的原因。当一个子查询以这种格式与一个主查询联接时就称相关查询。</p>
<p>通过使用NOT逻辑操作符,我们可以检索和EXISTS子查询相反的记录,从而可以得到所有没有任何发票的顾客的结果集。</p>
<p>SELECT *<br>
FROM tblCustomers AS A<br>
WHERE NOT EXISTS<br>
(SELECT * FROM tblInvoices<br>
WHERE A.CustomerID = tblInvoices.CustomerID)<br>
</p>
<p>如果你想得到更多的关于子查询的信息,在Office 助理或微软Access帮助窗体的Answer Wizard标志中输入SQL subqueries ,并单击Search。</p>
<p>连接<br>
在一个如同Access的相关数据库系统中,你会常常需要同时从多个工作表中摘出信息记录。这可以通过使用一个SQL JOIN语句来实现。JOIN语句可以让你从已经定义了相互关系的工作表中检索记录,而不用管记录和工作表之间的关系是一对一、一对多还是多对多。</p>
<p>内部连接<br>
内部连接,也被理解为对等连接,就是被使用的连接里最一般的形式。这种连接通过匹配一个各个工作表中共有的域值来从两个或更多的工作表中检索记录。你所连接的域必须具有类似的数据类型,但你就不能对MOMO和OLEOBJECT数据类型进行连接。为了建立一个INNER JOIN语句,在SELECT语句的FROM子句里使用INNER JOIN关键字。让我们使用INNER JOIN 建立所有拥有发票的顾客的结果集,并带上那些发票的时间和金额。</p>
<p>SELECT [Last Name], InvoiceDate, Amount<br>
FROM tblCustomers INNER JOIN tblInvoices<br>
ON tblCustomers.CustomerID=tblInvoices.CustomerID<br>
ORDER BY InvoiceDate<br>
</p>
<p>注意工作表名被INNER JOIN关键字所分开,并且相关的比较是在ON关键字的后面。对于相关的比较,你也可以使用<、 >、 <=、 >=或 <> 操作符,并且你也可以使用BETWEEN关键字。同时注意各个工作表只在比较关系中使用的ID域,它们都不是最后结果集的组成。</p>
<p>如果要进一步的限制SELECT 语句我们可以在ON子句中的比较连接后面使用WHERE子句。在下面的例子中我们通过只包括1998年1月1日以后的发票来缩小结果集。</p>
<p>SELECT [Last Name], InvoiceDate, Amount<br>
FROM tblCustomers INNER JOIN tblInvoices<br>
ON tblCustomers.CustomerID=tblInvoices.CustomerID<br>
WHERE tblInvoices.InvoiceDate > #01/01/1998#<br>
ORDER BY InvoiceDate<br>
</p>
<p>在希望连接多个工作表的案例中,你可以嵌入INNER JOIN子句。在这个例子里,我们将在过去的一个SELECT语句的基础上产生我们的结果集,但我们也将通过为tblShipping工作表添加INNER JOIN使结果包括每个顾客的所在城市和国家。</p>
<p>SELECT [Last Name], InvoiceDate, Amount, City, State<br>
FROM (tblCustomers INNER JOIN tblInvoices<br>
ON tblCustomers.CustomerID=tblInvoices.CustomerID)<br>
INNER JOIN tblShipping<br>
ON tblCustomers.CustomerID=tblShipping.CustomerID<br>
ORDER BY InvoiceDate<br>
</p>
<p>注意第一个JOIN子句为圆括号所包含以使之从逻辑上和第二个JOIN子句分开。而在FROM子句中使用一个第二个工作表的别名把一个工作表连接到自身也是可能的。让我们假设我们想找到所有具有相同的名的顾客记录。我们可以通过为第二个工作表创建一个别名“A”并查找其姓氏不同的记录来实现。</p>
<p>SELECT tblCustomers.[Last Name],<br>
tblCustomers.[First Name]<br>
FROM tblCustomers INNER JOIN tblCustomers AS A<br>
ON tblCustomers.[Last Name]=A.[Last Name]<br>
WHERE tblCustomers.[First Name]<>A.[First Name]<br>
ORDER BY tblCustomers.[Last Name]<br>
</p>
<p>外部连接</p>
<p>外部连接是在当记录保存在某一个工作表中时用于在多个工作表进行记录检索,即使在其它的工作表中没有匹配的记录也行。Jet 数据库引擎共支持两种类型的外部连接。考虑两个互相相近的工作表,一个在左边,另一个在右边。左外部连接将在右工作表中选择所有匹配比较关系标准的所有行和左工作表中的所有行,即使在右工作表中没有匹配记录存在。而右外部连接则是左外部连接的简单反转;即所有在右工作表中的行将被保存。</p>
<p>作为一个例子,让我们假设我们想测定每个顾客的所有发票数量,但如果一个顾客没有发票,我们希望通过消息“NONE”来显示其信息。</p>
<p>SELECT [Last Name] & ', ' & [First Name] AS Name,<br>
IIF(Sum(Amount) IS NULL,'NONE',Sum(Amount)) AS Total<br>
FROM tblCustomers LEFT OUTER JOIN tblInvoices<br>
ON tblCustomers.CustomerID=tblInvoices.CustomerID<br>
GROUP BY [Last Name] & ', ' & [First Name]<br>
</p>
<p>在前面的SQL语句中仍然有几个问题。第一个是对字符串连接操作符“&”的使用,这个操作符允许你把两个或更多的域连接到一起组成一个字符串。第二个是 immediate if(IIF)语句,它会检查合并后的字符串是否为空。如果为空,这个语句将返回消息“NONE”,而如果组合不是空,将返回组合后的值。最后一点是外部连接子句。使用左外部连接保存左工作表的行从而让我们可以看到所有的顾客,包括那些没有发票在帐目中的。</p>
<p>在一个多工作表的连接中外部连接可以被嵌套在内部连接里,但内部连接不可以被嵌套在外部连接中。</p>
<p>笛卡儿乘积<br>
当我们讨论联接时常常遇到的一个术语是笛卡儿乘积。笛卡儿乘积的定义为“把所有表单的所有行完全合并”。例如,如果你想不用任何约束把两个工作表联合在一起,你就完成了一个笛卡儿乘积。</p>
<p>SELECT *<br>
FROM tblCustomers, tblInvoices<br>
</p>
<p>这不是一个好东西,特别当你要处理的工作表中包含有成百上千行数据时。所以你应该通过约束你的连接来避免笛卡儿乘积。</p>
<p>The UNION operator<br>
虽然UNION 的操作也可以视为一个合并查询,但我们不可以技术性地把它看作是一个联接,它之所以被提到是因为它能把从多个来源获得的数据合成一个结果表单中,而这一点和某些类型的联接是类似的。UNION 操作一般被用来把来自表单、SELECT语句或查询的数据结合,并省略掉任何重复的行。所有的数据源必须有相同数目的域,不过这些域不一定要是相同的数据类型。让我们假设我们有一个雇员表单,其中具有和顾客工作表单相同的结构,那么我们希望合并这两个工作表得到一个姓名和电子邮件地址信息的列表。</p>
<p>SELECT [Last Name], [First Name], Email<br>
FROM tblCustomers<br>
UNION<br>
SELECT [Last Name], [First Name], Email<br>
FROM tblEmployees<br>
</p>
<p>如果你希望找到这些表中的所有域,我们可以使用TABLE关键字,如同下面一样:</p>
<p>TABLE tblCustomers<br>
UNION<br>
TABLE tblEmployees<br>
</p>
<p>UNION操作不会显示任何在两个表单中重复出现的记录,但它可以通过在UNION关键字后使用谓词ALL来覆盖重复信息,如下所示:</p>
<p>SELECT [Last Name], [First Name], Email<br>
FROM tblCustomers<br>
UNION ALL<br>
SELECT [Last Name], [First Name], Email<br>
FROM tblEmployees<br>
</p>
<p>转换语句</p>
<p>虽然转换语句也可以视为一个交叉表查询,但我们不可以技术性地把它看作是一个联接,它之所以被提到是因为它能把从多个来源获得的数据合成一个结果表单中,而这一点和某些类型的联接是类似的。</p>
<p>TRANSFORM 语句通常用于计算总数、平均值、数目以及其它
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -