![]() ![]() |
|
MSJetSQLforAccess2000中级篇(III) | |
作者:佚名 文章来源:不详 点击数 更新时间:2008/6/19 14:52:04 文章录入:杜斌 责任编辑:杜斌 | |
|
|
中级数据操纵语言 《基础Microsoft Jet SQL for access 2000》一文告诉我们如何使用SQL来检索和管理存储在数据库中的信息。本文的后面部分将讨论中级数据操纵语言(DML)语句,这将使得用户可以更好的控制信息检索和处理的方式。 谓词 ALL关键字 SELECT * 注意尽管这里ALL关键词并没有定义,但它是缺省值。我们也可以如下书写该语句: SELECT ALL * DISTINCT关键字 DISTINCT关键字用来控制结果集中重复的值如何进行处理,那些对于指定的列来说用户相同值的行将被过滤掉。如果多于指定的列大于一,则所有指定的列的结合将作为过滤条件。例如,如果用户查询Customers表中姓氏不同的记录,则返回的值都将是唯一的,任何重复姓氏的名字都将以结果集中的一个记录作为其结果。 SELECT DISTINCT [Last Name] 尤其要注意的是,使用DISTINCT关键字的查询所返回的结果集不能更新,即是只读的。 DISTINCTROW 关键字 例如,在我们的发票数据库中,每个顾客都可能没有、有一个或多个发票记录。假设我们希望找出有多少拥有多于一张发票的顾客,这时可以使用DISTINCTROW关键字来进行选择。 SELECT DISTINCTROW [Last Name], [First Name] 如果我们不使用DISTINCTROW 关键字,得到的将是每个顾客的所有发票记录的行。(这里的 INNER JOIN 语句将在后面的部分讲解)。 TOP关键字 SELECT TOP 3 InvoiceDate, Amount 我们也可以将PERCENT关键字和TOP关键字同时使用,来返回由ORDER BY子句所指定的数据行中顶部或底部的一定比例的行,如下所示: SELECT TOP 25 PERCENT InvoiceDate, Amount 注意如果用户没有定义ORDER BY 子句,则TOP关键字将毫无意义,返回的是随机采样的一些行。 要了解有关谓词的更多信息,请在Office 助手中或在Microsoft access 帮助的回答向导的标签页中输入ALL、DISTINCT等谓词,然后单击查找。 SQL 表达式 IN操作 SELECT * 通过使用NOT逻辑操作符,我们可以检索出IN操作的反操作结果,这个语句会返回所有不住在华盛顿州的销售部成员。 SELECT * BETWEEN操作 BETWEEN操作用于判断一个表达式的值是否介于一个特定的范围之间。如果这个表达式的值介于这个特定范围之间,包括范围开始和结束的值,这个BETWEEN操作返回True。如果这个表达式得值不属于这个范围,则BETWEEN操作返回值为False。假设我们想找到所以金额介于50美圆到100美圆之间的所有发票。我们最好在WHERE 子句使用BETWEEN 操作以及关键字AND设定范围。 SELECT * 通过使用NOT逻辑操作符,我们可以检索出BETWEEN操作的反操作结果,找到不在范围中的所有发票数量。 SELECT * FROM tblInvoices WHERE Amount NOT BETWEEN 50 and 100 注意这个范围可以设定为相反的顺序并依旧得到相同的结果 (BETWEEN 100 和 50),但许多的适用于ODBC的数据库要求这个范围遵从从头到尾的顺序。如果你设计你的应用程序可以兼容或升级为适用于ODBC的数据库,你就应该总是按照从头到尾的方法使用。 LIKE操作 SELECT * 为了返回所有的名字以字母J开头的顾客,我们使用星号通配符。 SELECT * 通过使用NOT逻辑操作符,我们可以检索出LIKE操作的反操作,并在列表中过滤掉所有的 Johnsons。 SELECT * 你在LIKE 操作样式里可以使用多种通配符,如下表所示: 通配符 *(星号) %(百分号) ?(问号) _(下划线) #(数字符号) [](方括号) !(感叹号) -(连字符) 注意: 上表所述的“%”和“_”通配符只能通过Jet OLE DB provider 或 ADO运行。如果通过. access SQL View 用户界面运行它们将获得一个空的结果集。 如果你想得到更多的通配符的信息,在Office 助理或微软access帮助窗体的Answer Wizard标志中输入wildcard characters,并单击Search。 IS NULL 操作符 SELECT * 通过添加NOT逻辑操作符,我们可以检索IS NULL操作符的反操作。在这个例子里,SQL语句将会除掉所有包含丢失的或未知值的发票记录。 SELECT * SELECT INTO 语句 当你用SELECT INTO 语句创建一个新工作表时,所有的新工作表里的域都继承于原始工作表。然而,不包括其他的工作表属性,如主关键字或索引都是在新工作表中被创建。一旦新的工作表被创建,你当然可以使用ALTER TABLE语句添加这些属性。 如果你要创建一个新的工作表,可以使用一个带有你希望在工作表种包含的列的域列表和你新工作表的名称的SELECT INTO 语句,并在FROM子句里提供数据资源。 SELECT * 为了为新的工作表指定确定的域,把域名列表里的原始工作表的域名用星号代替,并用AS关键字来命名新的工作表中的各列。 SELECT [First Name] & ' ' & [Last Name] AS FullName 如果要在一个已经存在的外部数据库里创建新的工作表,你可以用IN关键字。如果外部数据库不存在,SELECT INTO 语句将会返回一个错误信息。 SELECT * INTO tblNewCustomers IN 'C:\Customers.mdb' FROM tblCustomers 子查询 这里由三种基本的子查询形式,并且每种都使用不同种类的谓词。 IN子查询 SELECT * 通过使用NOT逻辑操作符,我们可以检索和IN子查询相反的记录,从而可以获得所有没有任何发票的顾客列表。 SELECT * ANY/SOME/ALL子查询 ANY、 SOME和ALL子查询谓词被用于比较主查询的记录和子查询的多个输出记录。ANY 和 SOME谓词是同义词并可以被替换使用。 当你需要从主查询中检索任何符合在子查询中满足比较条件的记录时可以使用ANY或 SOME谓词。谓词应该恰好放在子查询开始的括号前面。 SELECT * 注意由上面SQL语句所返回的结果集和IN子查询例子所返回的那个相同。而与ANY和SOME谓词的不同之处就在于它们都可以使用等于(=)以外的操作符,比如大于(>)和小于(<)。 SELECT * 当我们想在主查询中检索满足子查询比较条件的所有记录时使用谓词ALL。 SELECT * EXISTS子查询 EXISTS谓词是用于子查询来在一个结果集中检查所以存在值的记录。换句话说,就是如果子查询没有返回任何行,这个比较就False。而如果它返回了一行或多行,这个比较就为True。 SELECT * 注意在前面的SQL 语句里, tblCustomers 工作表使用了一个别名。这就是为何我们可以在后来的子查询中引用它的原因。当一个子查询以这种格式与一个主查询联接时就称相关查询。 通过使用NOT逻辑操作符,我们可以检索和EXISTS子查询相反的记录,从而可以得到所有没有任何发票的顾客的结果集。 SELECT * 如果你想得到更多的关于子查询的信息,在Office 助理或微软access帮助窗体的Answer Wizard标志中输入SQL subqueries ,并单击Search。 连接 内部连接 SELECT [Last Name], InvoiceDate, Amount 注意工作表名被INNER JOIN关键字所分开,并且相关的比较是在ON关键字的后面。对于相关的比较,你也可以使用<、 >、 <=、 >=或 <> 操作符,并且你也可以使用BETWEEN关键字。同时注意各个工作表只在比较关系中使用的ID域,它们都不是最后结果集的组成。 如果要进一步的限制SELECT 语句我们可以在ON子句中的比较连接后面使用WHERE子句。在下面的例子中我们通过只包括1998年1月1日以后的发票来缩小结果集。 SELECT [Last Name], InvoiceDate, Amount 在希望连接多个工作表的案例中,你可以嵌入INNER JOIN子句。在这个例子里,我们将在过去的一个SELECT语句的基础上产生我们的结果集,但我们也将通过为tblShipping工作表添加INNER JOIN使结果包括每个顾客的所在城市和国家。 SELECT [Last Name], InvoiceDate, Amount, City, State FROM (tblCustomers INNER JOIN tblInvoices ON tblCustomers.CustomerID=tblInvoices.CustomerID) INNER JOIN tblShipping ON tblCustomers.CustomerID=tblShipping.CustomerID ORDER BY InvoiceDate 注意第一个JOIN子句为圆括号所包含以使之从逻辑上和第二个JOIN子句分开。而在FROM子句中使用一个第二个工作表的别名把一个工作表连接到自身也是可能的。让我们假设我们想找到所有具有相同的名的顾客记录。我们可以通过为第二个工作表创建一个别名“A”并查找其姓氏不同的记录来实现。 SELECT tblCustomers.[Last Name], 外部连接 外部连接是在当记录保存在某一个工作表中时用于在多个工作表进行记录检索,即使在其它的工作表中没有匹配的记录也行。Jet 数据库引擎共支持两种类型的外部连接。考虑两个互相相近的工作表,一个在左边,另一个在右边。左外部连接将在右工作表中选择所有匹配比较关系标准的所有行和左工作表中的所有行,即使在右工作表中没有匹配记录存在。而右外部连接则是左外部连接的简单反转;即所有在右工作表中的行将被保存。 作为一个例子,让我们假设我们想测定每个顾客的所有发票数量,但如果一个顾客没有发票,我们希望通过消息“NONE”来显示其信息。 SELECT [Last Name] & ', ' & [First Name] AS Name, 在前面的SQL语句中仍然有几个问题。第一个是对字符串连接操作符“&”的使用,这个操作符允许你把两个或更多的域连接到一起组成一个字符串。第二个是 immediate if(IIF)语句,它会检查合并后的字符串是否为空。如果为空,这个语句将返回消息“NONE”,而如果组合不是空,将返回组合后的值。最后一点是外部连接子句。使用左外部连接保存左工作表的行从而让我们可以看到所有的顾客,包括那些没有发票在帐目中的。 在一个多工作表的连接中外部连接可以被嵌套在内部连接里,但内部连接不可以被嵌套在外部连接中。 笛卡儿乘积 SELECT * 这不是一个好东西,特别当你要处理的工作表中包含有成百上千行数据时。所以你应该通过约束你的连接来避免笛卡儿乘积。 The UNION operator SELECT [Last Name], [First Name], Email 如果你希望找到这些表中的所有域,我们可以使用TABLE关键字,如同下面一样: TABLE tblCustomers UNION操作不会显示任何在两个表单中重复出现的记录,但它可以通过在UNION关键字后使用谓词ALL来覆盖重复信息,如下所示: SELECT [Last Name], [First Name], Email 转换语句 虽然转换语句也可以视为一个交叉表查询,但我们不可以技术性地把它看作是一个联接,它之所以被提到是因为它能把从多个来源获得的数据合成一个结果表单中,而这一点和某些类型的联接是类似的。 TRANSFORM 语句通常用于计算总数、平均值、数目以及其它对记录进行总体统计的算法。并在计算后把结果信息显示在一个格子或数据表中,其中的数据分别按照行和列排列。一个TRANSFORM 语句的一般形式如下: TRANSFORM aggregating function 我们假设我们可以建立一个按照每一年为基础显示每个顾客的所有发票的数据表。这个列名应该是顾客的姓名,而行名则将是年份。让我们修改原来的SQL语句以符合转变后的语句. TRANSFORM 注意SUM函数是合计函数,组里的列的题头用在SELECT 语句的子句里,而行的名字由PIVOT关键字后所列出的域名决定。 如果你想知道关于连接的更多信息,在Office 助理或微软access帮助窗体得Answer Wizard标志中输入SQL joins,并单击Search。 |
|
![]() ![]() |