资源描述
第5章 数据查询和管理
关系数据的一个重要内容就是可以在任意两个表中存在关系。这种关系为查询带来新的内容,通过不同的连接查询可以将不同表之间的不同列返回到同一个结果集中,从而组成需要的结果。
在SQL Server 2008数据库系统中,SELCET语句是T-SQL语言中的核心内容。数据查询功能通过SELECT语句来实现。SELECT语句可以从数据库中按照用户的需要检索数据,并将查询结果以表格的形式输出。
本章将主要介绍SELECT语句的使用方法,以及如何连接多个表进行查询、使用子查询、XML查询等。
本章学习目标:
Ø 了解基本连接
Ø 掌握内连接的使用方法
Ø 掌握外连接的使用方法
Ø 掌握交叉连接
Ø 理解子查询的分类及其含义
Ø 掌握嵌套子查询
Ø 理解XML数据类型
Ø 掌握XQuery方法
5.1 SELECT简单查询
SELECT语句是数据库最基本的语句之一,同时也是SQL编程技术最常用的语句。使用SELECT语句不但可以在数据库中精确地查找某条信息,而且还可以模糊地查找带有某项特征的多条数据。这在很大程度上方便了用户查找数据信息。本节将主要介绍SELECT语句的语法基础,并通过实例演示SELECT语句的使用方法。
5.1.1 SELECT基本语法
SELECT语句是一个查询表达式,包括SELECT、FROM、WHERE、GROUP BY和ORDER BY子句。SELECT语句具有数据查询、统计、分组和排序的功能,可以精确地对数据库进行查找,也可以进行模糊查询。
SELECT语句有自己的语法结构,使用该语句时一定要严格执行其语法结构。加之其子句有很多,这里只列举它的主要子句格式,如下所示:
SELECT [ALL|DISTINCT]select_list
[INTO new_table]
FROM table_source
[WHERE search_conditions]
[GROUP BY group_by_expression]
[HAVING search_conditions]
[ORDER BY order_expression[ASC|DESC]]
上面格式中,SELECT查询语句中共有5个子句,其中SELECT和FROM语句为必选子句,而WHERE、GROUP BY和ORDER BY子句为可选子句。[]内的部分为可选项且大写内容为关键字。下面对各种参数进行详细说明。
l SELECT子句 用来指定由查询返回的列,并且各列在SELECT子句中的顺序决定了它们在结果表中的顺序。
l ALL|DISTINCT 用来标识在查询结果集中对相同行的处理方式。关键字ALL表示返回查询结果集的所有行,其中包括重复行;关键字DISTINCT表示若结果集中有相同的数据行则只保留显示一行,默认值为ALL。
l select_list 用来指定要显示的目标列,若要显示多个目标列,则各列名之间用半角逗号隔开;若要返回所有列,则可以用“*”表示。
l INTO new_table 用来创建一个新的数据表,new_table为新表的名称,表的数据为查询的结果集。
l FROM table_source子句 用来指定数据源,table_source为数据源表名称。
l WHERE search_conditions子句 用来指定限定返回的行的搜索条件,search_conditions为条件表达式。
l GROUP BY group_by_expression子句 用来指定查询结果的分组条件,即归纳信息类型,group_by_expression为分组所依据的表达式。
l HAVING search_conditions子句 用来指定组或聚合的搜索条件,search_conditions为分组后的条件表达式。
l ORDER BY order_expression[ASC|DESC]子句 用来指定结果集的排序方式,ASC表示结果集以升序排列,DESC表示结果集以降序排列,默认情况下结果集以ASC升序排列。
在使用SELECT语句时,还要遵守以下两条规则:
1.SELECT语法中子句的测试顺序
SELECT语句中的FROM、WHERE、GROUP BY和HAVING等子句称为表表达式,它们在执行SELECT语句时首先被测试,并且每个子句按照某种次序被依次测试。了解了这种测试顺序,在用户创建较复杂的SELECT语句时非常有用。
测试表示SELECT语句在系统中的执行,其结果是一个虚拟表,用于以后的测试。具体地说,前一个子句的测试结果将用于下一个子句,直到表表达式的每个子句都被测试完毕。SELECT语句中首先要测试的子句是FROM子句。如果指定了WHERE子句,那么FROM子句的测试结果将用于WHERE子句。如果没有WHERE子句,那么FROM子句的测试将用于下一个指定的子句。在表达式中的最后一个子句被测试完之后,此时的测试结果才用于SELECT子句,而SELECT子句的测试结果用于ORDER BY子句。总的来说,SELECT语句的测试顺序为:
FROM子句
WHERE子句(可选)
GROUP BY子句(可选)
HAVING子句(可选)
SELECT子句
ORDER BY子句(可选)
了解该测试顺序对于提高查询效率有很大意义,这种效率在简单的查询语句中表现的并不明显。但是一旦用户使用了复杂的查询语句,尤其是在处理连接和子查询时,不了解SELECT语句的测试顺序将严重影响SELECT语句的查询效率。
2.引用对象名称约定
若使用SELECT语句查询时,所引用对象的数据库不是当前数据库或引用的列名不明确时,为了保证查询的正确性,在引用数据表或列时需要使用数据库或数据表名来限定数据表或列的名称。
l 如果要引用某数据表名称,而当前数据库不是所引用对象的数据库,就需要使用USE语句将当前数据库设置为该表所在的数据库。例如,当前数据库为“网店场管理系统”,而现在要引用“工资管理系统”数据库中的“员工信息”数据表,这时需要在前面加上“USE工资管理系统”语句。
l 如果当前使用的列名不明确是哪个数据表中的列,就需要通过给该列指定表名来确定其数据源。例如,在同一数据表中的多个表中都存在着名为“员工编号”的列,当进行多表操作时,如果只使用“员工编号”指定选择条件,就会出现歧义,所以需要通过表名来明确所要指定的“员工编号”列,即使用“员工信息.员工编号和工资信息.员工编号”表示。
5.1.2 使用SELECT语句
前面已经详细介绍了SELECT及其子句的语法格式,本节将主要列举实例,单独介绍SELECT语句的使用方法而并不涉及它的各个子句。关于其子句的使用方法及其特点将在后面的章节中详细介绍。
1.使用SELECT获取表中所有信息
SELECT语句可以返回表中所有的内容,并按照表中的顺序与格式进行排列,其语法格式为:
SELECT *
FROM table_list
其中值得注意的是“*”,它表示源表中所有的信息,而table_list则表示查找数据信息的源表。由于它并不改变源表中的信息格式,因此使用该语句得到的查询结果可以看到源表的结构。例如,查询“网店购物系统”数据库中“商品信息”表中的所有列,在数据库引擎查询窗口中输入SELECT语句:
USE 网店购物系统
SELECT *
FROM 商品信息
执行上面命令后,可以在SQL Server 2008窗口中看到如图5-1所示的结果。
图5-1 查询表中的所有列
2.使用SELECT获取表中若干列
使用SELECT还可以获取表中指定的一列或者几列数据。返回结果中列的排列顺序为用户查询语句中指定的顺序,而各列中的数据顺则是源表的排列序列。使用SELECT获取表中若干列的语法如下所示:
SELECT column1, column2, column3
FROM table_list
上面信息中column表中源表中某一列,如果需要查询列数较多,各列之间应使用“,”符号分隔。例如同样在“商品信息”表中,查询“商品名称”、“商品价格”和“库存数量”三列数据,可以使用下面语句:
USE 网店购物系统
SELECT 商品名称, 商品价格, 库存数量 FROM 商品信息
执行完该语句后,结果如图5-2所示。
图5-2 查询多列的结果
在获取表中某些列时,在返回结果中用户可以为这些列重命名,这种操作并不改变数据库中表的列名,只显示在返回结果中。为列重命名的语法格式为:
SELECT column1 AS Name1,
column2 AS Name2,
column3 AS Name3
FROM table_list
其中AS Name为重命名过程,上面格式中将column1命名为Name1.例如将“商品名称”、“商品价格”和“库存数量”三列重命名为“货物名称”、“销售价格”和“剩余数量”,使用如下的语句。
USE 网店购物系统
SELECT 商品名称 AS 货物名称, 商品价格 AS销售价格, 库存数量 AS 剩余数量
FROM 商品信息
执行语句后,可以得到如图5-3所示的结果。
图5-3 对列名进行重命名
3.使用SELECT获取相异行
在数据库中数据难免会出现重复行的现象,例如“网店购物系统”数据库中“注册会员”表的“会员地址”列记录了注册会员所在的地区或城市,而有些注册会员生活在同一个城市。如果用户希望在查询返回结果删除重复行,可以在SELECT子句中使用DISTINCT关键字。
首先使用下面的语句查看“网店购物系统”数据库中“注册会员”表“会员地址”列中的信息,查询语句如下所示:
USE 网店购物系统
SELECT 会员地址 FROM 注册会员
执行语句后,得到如图5-4所示的结果。
图5-4 获取单列信息
此时,用户可以使用DISTINCT关键字重新获得一列值,从而去除了相同的行,语句如下所示。
USE 网店购物系统
SELECT DISTINCT 会员地址 FROM 注册会员
执行语句后,得到如图5-5所示的结果。
图5-5 获取相异行
4.返回若干行
前面介绍的几种方法可以分别获得表的全部信息或单独获取某个列,使用SELECT还可以指定表中返回的行数,使用方法如下所示。
SELECT [TOP n] [*|column]
FROM table
TOP n用于指定查询结果返回的行数。该返回值有个特点:其返回结果一定是返回表中从上往下的n行信息。TOP n与“*”连用表示返回该表中所有列的前n条信息,而与column连用表示返回某column列的前n条信息。
例如返回“注册会员”表中“会员地址”列的前10条信息,可以使用下面的语句:
USE 网店购物系统
SELECT TOP 10 会员地址
FROM 注册会员
执行该语句后,可以得到如图5-6所示的结果。
图5-6 获取前10行的信息
5.1.3 使用From子句
FROM子句是SELECT语句中必不可少的子句,该语句用于指定要读取的数据所在的一个表或几个表的名称,使用FROM子句表示要输出信息的来源。FROM子句的基本语法格式如下所示:
FROM table_source
其中,table_source指定要在Transact-SQL语句中使用的表、视图或派生表源(有无别名均可)。虽然语句中可用的表源个数的限值根据可用内存和查询中其他表达式的复杂性而有所不同,但一个语句中最多可使用256个表源。单个查询可能不支持最多有256个表源。可将table变量指定为表源。
如果查询中引用了许多表,查询性能会受到影响。编译和优化时间也受到其他因素的影响。这些因素包括:每个<table_source>是否有索引和索引视图,以及SELECT语句中<select_list>的大小。表源在FROM关键字后的顺序不影响返回的结果集。如果FROM子句中出现重复的名称,SQL Server会返回错误。
在指定table_source表的同时也可以使用AS关键字给该表定义一个别名,别名可带来使用上的方便,也可用于区分自联接或子查询中的表或视图。别名往往是一个缩短了的表名,用于在联接中引用表的特定列。如果联接中的多个表中存在相同的列名,SQL Server要求使用表名、视图名或别名来限定列名。如果定义了别名则不能使用表名。
下面来对“网店购物系统”数据库中的“注册会员”表进行简单查询,并对“注册会员”表定义别名为“会员信息”。具体查询语句如下所示:
USE 网店购物系统
SELECT * FROM 注册会员 AS 会员信息
执行该语句查询,得到结果如图5-7所示。
图5-7 查询结果
5.1.4 使用WHERE子句
在SQL Server数据库中查询数据时,有时需要定义严格的查询条件,只查询所需要的数据,而并非是数据表中的所有数据,那么就可以使用SELECT语句中的WHERE子句来实现。它类似一个筛选器,通过用户定义的查询条件,来保留从FROM子句中返回并满足条件的数据。
WHERE子句被用于选取需要检索的数据行,灵活地使用WHERE子句能够指定许多不同的查询条件,以实现更精确的查询,如精确查询数据库中某条语句的某项数据值或在WHERE子句中使用表达式。
在SELECT查询语句中,使用WHERE子句时一般语法结构为:
SELECT condition FROM table WHERE searchcondition
其中,search_conditions为用户选取所需查询的数据行的条件,即查询返回的行记录的满足条件。对于用户所需要的所有行,search_conditions条件为true;而对于其他行,search_conditions条件为false或者未知。WHERE子句使用灵活,searchcondition有多种使用方式,表5-1列出了WHERE子句中可以使用的条件。
表5-1 WHERE子句使用的条件
类别
运算符
说明
比较运算符
=、>、<、>=、<=、<>
比较两个表达式
逻辑运算符
AND、OR、NOT
组合两个表达式的运算结果或取反
范围运算符
BETWEEN、NOT BETWEEN
搜索值是否在范围内
列表运算符
IN、NOT IN
查询值是否属于列表值之一
字符匹配符
LIKE、NOT LIKE
字符串是否匹配
未知值
IS NULL、IS NOT NULL
查询值是否为NULL
针对表5-1列举的查询条件,下面将详细介绍他们在WHERE子句中的使用方法及其功能。
1.比较运算符
WHERE子句的比较运算符主要有=、<、>、>=、<=、<>和!=,分别表示等于、小于、大于、大于等于、小于等于、不等于(<>和!=都表示不等于),使用他们对查询条件进行限定。下面通过几个实例,详细介绍这些比较运算符的使用方法。
l 等于“=”运算符
在“网店购物系统”数据库“商品信息”表中查询商品编号为45104017的“商品名称”、“商品价格”以及“库存数量”,此时,用户可以使用下面的语句:
USE 网店购物系统
SELECT 商品名称, 商品价格, 库存数量 FROM 商品信息
WHERE 商品编号 ='45104017'
上面语句中使用“商品编号 ='45104017'”指定查询条件,且该条件中“=”后面的内容使用单引号括起来。执行该语句后,得到结果如图5-8所示。
图5-8 使用等于运算符指定查询条件
l 使用小于“<”运算符
小于运算符使用方法和注意事项与等于运算符基本相同,使用小于运算符可以指定查询的某个范围,例如查询“商品信息”表中“商品价格”小于300元的“商品编号”、“商品名称”以及“库存数量”,使用下面语句:
USE 网店购物系统
SELECT 商品名称, 商品价格, 库存数量 FROM 商品信息
WHERE 商品价格 <'300'
执行该语句后,得到结果如图5-9所示。
图5-9 使用小于运算符指定查询条件
l 使用不等于运算符
比较运算符中!=和<>都表示不等于,例如查询“商品信息”表中“商品价格”不等于299元的“商品编号”“商品名称”以及“商品价格”,使用下面语句:
USE 网店购物系统
SELECT 商品编号,商品名称, 商品价格 FROM 商品信息
WHERE 商品价格 !<'299'
执行该语句,得到的结果如图5-10所示。
图5-10 使用不等于运算符指定查询条件
上面使用!=符号,其中!也是一种运算符,如!<表示不小于(大于等于),而!>表示不大于(小于等于)。
2.逻辑运算符
有时,在执行查询任务时,仅仅指定一个查询条件不能够满足用户需求,此时需要指定多个条件来限制查询,那么就要使用逻辑运算符将多个查询条件连接起来,同时指定多个条件进行查询。
WHERE子句中可以使用AND、OR和NOT这三个逻辑运算符,表5-2列举了它们的作用与使用方法。
表5-2 逻辑运算符的功能
运算符
功能
示例
AND
在使用AND连接所有条件中,都为true时才会返回查询结果。
Express1 AND Express2
OR
在使用OR连接的所有条件中,只要其中有一个条件满足就返回查询结果。
Express1 OR Express2
NOT
取反,条件不成立时返回查询结果
NOT Express,Express不成立时返回结果。
这三个逻辑运算符可以混合使用,在WHERE子句中使用逻辑运算符来限定查询条件的语法格式为:
WHERE NOT expression|expression1 logical_operator expression2
其中,logical_operator表示逻辑运算符AND和OR中的任意一个。如果在WHERE子句中使用NOT运算符,则将NOT放在表达式的前面。
例如,在“网店购物系统”数据库中,查询“商品信息”表中商品价格>=300,且商品价格<500的“商品编号”、“商品名称”以及“库存数量”,使用下面语句:
USE 网店购物系统
SELECT 商品编号,商品名称, 库存数量 FROM 商品信息
WHERE 商品价格 >=300 AND 商品价格<500
上面语句中使用了AND连接两个条件,当两个条件都成立时,则可以得到如图5-11所示的结果。
图5-11 使用AND运算符
如果使用NOT和OR运算符,查询商品价格>=300,而库存数量<100时,可以使用下面的语句:
USE 网店购物系统
SELECT 商品编号,商品名称, 库存数量 FROM 商品信息
WHERE NOT(商品价格 >=300 OR 库存数量<100)
默认情况下,NOT只对紧跟着它后面的那个条件取反,因此使用NOT运算符时,如果连接多个条件同时取反,需要将这多个条件用括号括起来。
执行上面的语句,得到的结果如图5-12所示。
图5-12 使用NOT和OR运算符
NOT运算符使用很灵活,在WHERE子句可以与多种条件共用,例如NOT LIKE、NOT BETWEEN、IS NOT NULL等。当NOT与AND或OR结合使用时,具有如下规则:
NOT(A AND B)=(NOT A)OR(NOT B)
NOT(A OR B)=(NOT A)AND(NOT B)
NOT(NOT A)=A
根据该规则,可以将上面实例中的语句更改为如下形式,执行语句,同样可以得到5-12所示的结果。
USE 网店购物系统
SELECT 商品编号,商品名称, 库存数量 FROM 商品信息
WHERE (NOT商品价格 >=300) AND(NOT 库存数量<100)
在使用AND和OR两个逻辑运算符时,它们只对紧挨着它的两个条件有限定作用,如果它们需要连接一组条件时,需要将这一组条件用括号括起来。例如下面的语句:
USE 网店购物系统
SELECT 商品编号,商品名称, 商品价格 FROM 商品信息
WHERE 库存数量=100 AND
(商品价格>250 OR 商品价格<300)
语句中使用AND连接一组条件,该组条件使用了括号,执行该语句后,得到的结果如图5-13所示。
图5-13 执行一组条件后的结果
3.使用IN条件
在SQL Server数据库中,执行查询操作时,会遇到查询某表达式的取值属于某一列表之一的数据,虽然可以结合使用比较运算符和逻辑运算符来满足查询条件,但是这样编写SELECT语句会使SELECT语句的直观性下降。使用IN或NOT IN 关键字限定查询条件,更能直观地查询表达式是否在列表值中,也可作为查询特殊信息集合的方法。使用IN关键字来限定查询条件的基本语法格式为:
WHERE expression [NOT] IN value_list
上述语句中NOT为可选值,而value_list表示列表值,当值不止一个时需要将这些值用括号括起来,各列表值之间使用逗号隔开。
例如在“商品信息”表中查询“商品编号”为100000000484449、100000000501662、100000000305779、100000000538694的“商品名称”、“商品价格”和“库存数量”,可以使用下面语句:
USE 网店购物系统
SELECT 商品名称, 商品价格,库存数量 FROM 商品信息
WHERE 商品编号
IN ('100000000484449','100000000501662','100000000305779','100000000538694')
上面语句中
('100000000484449','100000000501662','100000000305779','100000000538694')定义了一个列表值,查询的内容为“商品编号”属于列表值中的内容。执行语句,得到结果如图5-14所示。
图5-14 使用IN条件
从执行语句和返回结果中可以看到,使用IN可以返回一组特定的结果,上面的实例也可以使用逻辑运算符写成下面的形式:
USE 网店购物系统
SELECT 商品名称, 商品价格,库存数量 FROM 商品信息
WHERE
商品编号 ='100000000484449' OR
商品编号 ='100000000501662'OR
商品编号 ='100000000305779'OR
商品编号 ='100000000538694'
通过比较两种写法可以看出,在这种情况下使用逻辑运算符明显比较复杂,SELECT也比较长。因此选用合适的条件进行SELECT查询,能提高语句的可读性并能提高执行效率。
使用IN条件时还应注意,在列表值中各值必须具有相同的数据类型。另外,列表值中各项不能包含NULL值。同样,在使用NOT IN时也应该注意这些,例如使用下面的语句查询不属于列表值的内容:
USE 网店购物系统
SELECT 商品名称, 商品价格,库存数量 FROM 商品信息
WHERE 商品编号
NOT IN ('100000000484449','100000000501662','100000000305779','100000000538694')
上面语句表示查询返回结果排除了列表值中的内容,可以得到如图5-15所示的结果。
图5-15 使用NOT IN 条件
4.使用BETWEEN条件
在WHERE子句中使用BETWEEN关键字查找在某一范围内的数据,也可以使用NO BETWEEN关键字查找不在某一范围内的数据。使用BETWEEN关键字来限定查询条件的语法格式如下所示:
WHERE expression [NOT] BETWEEN value1 AND value2
其中NOT为可选项,value1表示范围的下限,value2表示范围的上限。注意value1必须不大于value2,绝对不允许value1大于value2。
例如,在“商品信息”表中查询商品价格在200与300之间商品的“商品编号”、“商品名称”“商品价格”和“库存数量”,可以使用下面语句:
USE 网店购物系统
SELECT 商品编号,商品名称, 商品价格,库存数量 FROM 商品信息
WHERE 商品价格 BETWEEN '200'AND '300'
上面的语句中,通过在WHERE子句中使用BETWEEN关键字查询了“商品价格”在200-300之间的所有数据。执行语句后,得到如图5-16所示的结果。
图5-16 使用BETWEEN条件
如果想查询“商品价格”在200至300之外的所有数据,则只需在BETWEEN关键字前面加上NOT即可,语句如下所示:
USE 网店购物系统
SELECT 商品编号,商品名称, 商品价格,库存数量 FROM 商品信息
WHERE 商品价格 NOT BETWEEN '200'AND '300'
5.使用LIKE匹配条件
在SQL Server数据库中,执行查询任务时,可能无法确定某条记录中的具体信息,如果要查找该记录时则需要使用模糊查询。比如查找会员信息中姓“王”的相关信息,或者查询会员所在地区为“北京”的相关信息。
在WHERE子句中使用LIKE与通配符搭配使用,可以实现模糊查询。在WHERE子句中使用LIKE关键字的作用是将表达式与字符串作比较。LIKE关键字同样也可以与NOT运算符一起使用。使用LIKE关键字限定查询条件的语法格式为:
WHERE expression [NOT] LIKE 'string'
其中,[NOT]为可选项,'string'表示进行比较的字符串。WHERE子句实现对字符串的模糊匹配,进行模糊匹配时在string字符串中使用通配符。在SQL Server 2008中使用含有通配符时必须将字符串连同通配符用单引号括起来。表5-3中列出了几种比较常用的通配符表示方式和说明。
表5-3 通配符及其说明
通配符
说明
示例
%
任意多个字符
H% 表示查询以H开头的任意字符串,如Hello。
%h 表示查询以h结尾的任意字符串,如Growth。
%h% 表示查询在任何位置包含字母h的所有字符串,如hui,zhi。
_
单个字符
H_ 表示查询以H开头,后面跟任意一个字符的两位字符串,如Hi,He。
[ ]
指定范围的单个字符
H[ea]% 表示查询以H开头,第二个字符是e或a的所有字符串,如Health,Hand。
[A-G]% 表示查询以A到G之间的任意字符开头的字符串,如Apple,Banana,Guide。
[^ ]
不在指定范围的单个字符
H[^ea]% 表示查询以H开头,第二个字符不是e或a的所有字符串,如Hope,Hub。
[^A-G]% 表示查询不是以A到G之间的任意字符开头的字符串,如Job,Zoo。
例如,在“注册会员”表中查询会员地址为上海的“会员编号”、“会员名称”“消费总额”和“历史记录”,可以使用下面语句:
USE 网店购物系统
SELECT 会员编号,会员名称, 消费总额,历史记录 FROM 注册会员
WHERE 会员地址 LIKE '上海%'
上面语句中使用LIKE与通配符%结合查询所在地区为上海的所有会员,执行语句后,得到如图5-17所示的结果。
图5-17 使用LIKE和%通配符
6.使用IS NULL条件
NULL表示未知、不可用或将在以后添加数据,NULL值与零、零长度的字符串或空白(字符值)的含义不同。相反,空值可用于区分输入的是零(数值列)或空白(字符列)还是无数据输入(NULL可用于数值列和字符列)。
在WHERE子句中使用IS NULL条件可以查询某一数据值为NULL的数据信息。反之要查询数据库中的值不为NULL时,可以使用IS NOT NULL关键字。使用IS NULL条件的语法格式为:
WHERE column IS [NOT] NULL
例如,在“注册会员”表中查询“历史记录”列为NULL的注册会员信息,可以使用下面的语句:
USE 网店购物系统
SELECT 会员编号,会员名称, 消费总额 FROM 注册会员
WHERE 历史记录 IS NULL
在上面的语句中,WHERE子句限定了“历史记录”列为NULL的会员信息,执行语句后,得到如图5-18所示的结果。
图5-18 使用IS NULL条件
5.1.5 使用ORDER BY子句
ORDER BY子句一般位于SELECT语句的最后,它的功能是对查询返回的数据进行重新排序。用户可以通过ORDER BY子句来限定查询返回结果的输出顺序,如正序或者倒序等。
ORDER BY子句在SELECT语句中的语法格式为:
ORDER BY order_expression [ASC | DESC]
其中,order_expression表示用于排序列或列的别名及表达式。当有多个排序列时,每个排序列之间用半角逗号隔开,而且列后都可以跟一个排序要求:当排序要求为ASC时,行按排序列值的升序排序;排序要求为DESC时,结果集的行按排序列值的降序排列。如没指定排序要求,则使用默认值ASC。
例如,将“网店购物系统”数据库的“商品信息”表按照“商品价格”进行升序排列,以查看商品的信息。可以使用下面的语句:
USE 网店购物系统
SELECT * FROM 商品信息
ORDER BY 商品价格 ASC
上面的语句,使用ORDER BY指定“商品价格”进行升序排序。执行语句后,得到如图5-19所示的结果。
图5-19 使用ORDER BY进行升序的结果
默认情况下为正序排列,因此在使用ORDER BY子句时不需要指定ASC,系统也会自动进行正序排列。
如果用户对表比较熟悉,在对列进行排序时,可以直接指定列在表中的位置号,以方便操作。例如,“会员编号”列在“注册会员”表中为第1列。上列语句就可以直接将排序依据的“会员编号”列改为1。
使用ORDER BY子句还可以同时对多个列进行排序。例如,对【工资管理系统】数据库中的所有员工信息先按【工资级别】进行升序排列,如果【工资级别】列中有相同的数据,那么再按照【工龄】进行降序排列,具体的SELECT语句如下所示:
USE 工资管理系统
SELECT * FROM 员工信息 ORDER BY 工资级别 ASC,工龄 DESC
5.1.6 使用GROUP BY子句
数据库具有基于表的特定列对数据进行分析的能力。可以使用GROUP子句对某一列数据的值进行分组,分组可以使同组的元组集中在一起,这也使数据能够分组统计。换句话说,就是GROUP BY子句用于归纳信息类型,以汇总相关数据。
GROUP BY子句的语法格式为:
GROUP BY group_by_expression [WITH ROLLUP|CUBE]
其中,group_by_expression表示分组所依据的列,ROLLUP表示只返回第一个分组条件指定的列的统计行,若改变列的顺序就会使返回的结果行数据发生变化。CUBE是ROLLUP的扩展,表示除了返回由GROUP BY子句指定的列外,还返回按组统计的行。GROUP BY子句通常与统计函数联合使用,如COUNT、SUM等。在表5-4中列出了几个常用的统计函数及功能。
表5-4 常用统计函数
函数名
功能
COUNT
求组中项数,返回整数
SUM
求和,返回表达式中所有值的和
AVG
求均值,返回表达式中所有值得平均值
MAX
求最大值,返回表达式中所有值得最大值
MIN
求最小值,返回表达式中所有值的最小值
ABS
求绝对值,返回数值表达式的绝对值
ASCII
求ASCII码,返回字符型数据的ASCII
RAND
产生随机数,返回一个位于0和1之间的随机数
在使用GROUP BY子句时,将GROUP BY子句中的列称为分割列或分组列,而且必须保证SELECT语句中的列是可计算的值或者在GROUP BY列表中。
例如,要在【工资管理系统】数据库的【员工信息】表中按照【所任职位】查询出对应职位上的统计人数,具体SELECT语句如下所示:
USE 工资管理系统
SELECT 所任职位,COUNT(员工编号) AS 职位上的人数 FROM 员工信息 GROUP BY 所任职位
执行上述语句后,将对【员工信息】表中【所任职位】列进行分组,并且对于每一组使用COUNT()函数统计出各职位上的人数,语句的执行结果如图5-20所示。
图5-20 使用GROUP BY子句进行分组统计
GROUP BY子句通常用于对某个子集或其中的一组数据,而不是对整个数据集中的数据进行合计运算。在SELECT语句中指定的列必须是GROUP BY子句中的列名,或者被聚合所使用的列,并且在GROUP BY子句中必须使用列的名称、而不能使用AS子句中指定的列的别名。
5.1.7 使用HAVING子句
通常情况下,HAVING子句常与GROUP BY子句共同使用。大家知道,WHERE子句用于限定每一行的查询条件,而HAVING子句则限定分组统计值。使用HAVING子句,可以指定分组或聚合的搜索条件。
HAVING子句的语法格式为:
HAVING search_conditions
其中,search_conditions为查询所需的条件,即返回查询结果的满足条件。在使用GROUP BY子句时,HAVING子句将限定整个GROUP BY子句创建的组,其具体规则如下:
l 如果指定了GROUP BY子句,则HAVING子句的查询条件将应用于GROUP BY子句创建的组。
l 如果指定了WHERE子句,而没有指定GROUP BY子句,那么HAVING子句的查询条件将应用于WHERE子句的输出结果集。
l 如果既没有指定WHERE子句,又没有指定GROUP BY子句,那么HAVING子句的查询条件将应用于FROM子句的输出结果集。
对于所允许的元素,HAVING子句对GROUP BY子句设定查询条件的方式与WHERE子句对SELECT语句设定查询条件的方式类似,但包含聚集函数上却不相同。HAVING子句中可以包含聚集函数,而WHERE子句不可以。而且HAVING子句中的每一元素都必须出现在SELECT语句的列表中。
5.2 SELECT高级查询
在实际查询应用中,用户所需要的数据并不全部都在一个表或视图中,而在多个表中,这时就要使用多表查询。多表查询用多个表中的数据来组合,再从中获取出所需要的数据信息。多表查询实际上是通过各个表之间的共同列的相关性来查询数据的,是数据库查询最主要的特征。多表查询首先要在这些表中建立连接,表之间的连接就是连接查询的结果集或结果表。而实现连接的结果是在向数据库添加新类型的数据方面没有限制的,具有很大的灵活性。通常总是通过连接创建一个新表,以包含不同表中的数据。如果新表有合适的域,就可以将他连接到现有的表中。
5.2.1 基本连接
在进行多表操作时,最简单的连接方式就是在SELECT语句列表中引用多个表的字段,其FROM子句中用半角逗号将不同的基本表隔开。如果使用WHERE子句创建一个同等连接则能使查询结果集更加丰富,同等连接是指第一个基表中的一个或多个列值与第二个基表中对应的一个或多个列值相等的连接。通常情况下,一般使用键码列建立连接,即一个基表中的主键码与第二个基表中的外键码保持一致,以保持整个数据库的参照完整性
展开阅读全文