1、第4章数据检索第第4章数章数 据据 检检 索索4.1 SELECT语句语句4.2 基本数据检索方法基本数据检索方法 4.3 高级数据检索技术高级数据检索技术 习题习题4 第4章数据检索4.1SELECT语句语句数据库查询是数据库的核心操作。在SQL语言中,通常用SELECT语句检索数据库,查找到满足所设定条件的数据集合。该语句具有灵活的使用方式和丰富的功能,是SQL语言中最强大也是最复杂的语句,它的一般格式为第4章数据检索SELECT ALL|DISTINCT INTO table_name|view_nameFROM table_name|view_name,.nWHERE GROUP BY
2、 HAVING ORDER BY ASC|DESCCOMPUTE;第4章数据检索其中,尖括号中的内容是必选项;方括号里的内容是可选项,根据功能的不同可以选也可以不选。SELECT语句由几个子句组成,SELECT子句和FROM子句是必需的,其余几个子句是可选的。每个子句的功能如下:SELECT子句:列出要被检索的数据项列表。数据项可以是数据库中的字段名、常量或SQL表达式,各项之间用逗号分隔。第4章数据检索 INTO子句:创建新表并将查询结果插入新表中。用户若要执行带 INTO 子句的 SELECT 语句,必须在目的数据库内具有 CREATE TABLE权限。SELECT.INTO不能与 COM
3、PUTE 子句一起使用。FROM子句:指出要从哪些表或视图中检索数据。WHERE子句:指出被检索的数据要满足哪些条件。GROUP BY子句:用于汇总查询。将查询结果按指定条件分组,然后对每一组生成一条汇总查询记录。第4章数据检索 HAVING子句:用于指出哪些由GROUP BY子句生成的组出现在结果表中。ORDER BY子句:将结果数据按指定的一个或多个字段排序。COMPUTE子句:用来在结果集的末尾生成一个数据汇总行。整个SELECT语句的含义是:根据WHERE子句的条件表达式,从FROM子句指定的基本表或视图中找出满足条件的元组,再按SELECT子句中的目标列表达式,选出元组中的属性值形成
4、结果表。第4章数据检索如果有GROUP BY子句,则将结果按group_by_expression的值进行分组(该属性列值相等的元组为一组)。通常会在每组中使用聚合函数。如果GROUP BY子句带HAVING子句,则只输出满足指定条件的元组。如果有ORDER BY子句,则结果表还要按order_expression的值进行升序或降序排序。第4章数据检索在执行SELECT语句之前,需要选择数据库。pubs是一个SQL Server在安装时创建的范例数据库,库中包含供虚拟的出版商使用的多个表。本章中的例程如不特别指明,都是基于这个数据库来设计的。第4章数据检索4.2基本数据检索方法基本数据检索方法
5、基本数据检索方法中SELECT语句相对简单,一般只包括SELECT子句、FROM子句和WHERE子句,有时也会含有ORDER子句。阅读一个SELECT-FROM-WHERE语句的最简单的方法是:首先看FROM子句,找出该查询涉及到哪些关系;接着看WHERE子句,了解要查询的数据应满足的条件;最后看SELECT子句,确定查询结果所包含的数据列。第4章数据检索4.2.1选择数据列选择数据列pubs数据库中有一个authors表,包括au_id(编号)、au_lname(姓)、au_fname(名字)、phone(电话号码)、address(地址)、city(城市)、state(州)和zip(邮政编
6、码)字段。通过在SELECT语句的第一部分指定它们,可以从表中取出任何一个字段,也可以在一个SELECT语句中一次取出多个字段。第4章数据检索1.选择指定的数据列选择指定的数据列在很多情况下,用户只对表中的一部分数据列感兴趣,这时可以在SELECT子句中指定要检索的数据列。例例4-1 查询电话号码:SELECT phoneFROM authors第4章数据检索这个查询执行后,取出表authors中的所有电话号码,结果如下(因为篇幅有限,没有将数据行全部列出来,在这里用省略号代替它们):phone408 496-7223415 986-7020415 548-7723408 286-2428(所
7、影响的行数为 23 行)第4章数据检索这个查询执行后,取出了表authors中的所有电话号码。通过在SELECT语句中指定字段名字,可以从表中取出任何一个数据列;也可以在一个SELECT语句中指定多个字段名,一次取出多个数据列,注意字段名之间要用逗号隔开。例例4-2 查询authors表多个字段:SELECT au_fname,au_lname,phone FROM authors 这个SELECT语句执行后,将取出这三个列的所有值。检索结果如下所示:第4章数据检索au_fname au_lname phone-Johnson White 408 496-7223Marjorie Green
8、415 986-7020Cheryl Carson 415 548-7723Michael OLeary 408 286-2428Dean Straight 415 834-2919(所影响的行数为 23 行)第4章数据检索2.选择全部数据列选择全部数据列有时需要检索全部数据列,比如想看看表中都包含哪些数据列。这时可以用星号(*)来代替所有数据列的名字,从一个表中检索出所有的字段。例例4-3 查询authors表的所有字段:SELECT*FROM authors 这个SELECT语句执行后,表中的所有字段的值都被取出。结果如下:第4章数据检索au_id au_lname au_fname ph
9、one address city state zip contract-172-32-1176 White Johnson 408 496-7223 10932 Bigge Rd.Menlo Park CA 94025 1(所影响的行数为 23 行)第4章数据检索3.改变列标题改变列标题在默认情况下,检索结果所显示出来的列标题就是在创建表时使用的列名。表中的列名往往比较简练,不便于阅读理解。SQL语言中提供几种方法来改变列标题,以使其变得意义更加明确和直观易读。第4章数据检索1)使用AS关键词使用AS关键词的形式为:列名 AS 新标题例例4-4 给查询结果列标题:SELECT au_lname
10、 AS author last name,phone AS phone numberFROM authors检索结果如下所示。其中列名au_lname改为author last name,列名phone 改为phone number。第4章数据检索author last name phone number-White 408 496-7223Green 415 986-7020Carson 415 548-7723OLeary 408 286-2428Straight 415 834-2919(所影响的行数为 23 行)第4章数据检索2)使用“=”使用“=”的形式为:新标题=列名如,例4-4可
11、以改写为SELECT author last name=au_lname,phone number=phoneFROM authors执行后,得到的检索结果与上例完全相同。第4章数据检索3)使用空格使用空格的形式为:列名 新标题 如,例4-4可以改写为SELECT au_lname author last name,phone phone numberFROM authors第4章数据检索4.使用文字串使用文字串通常,直接阅读SELECT语句的检索结果是一件很麻烦的事,因为显示出来的数据只是一些不连贯的信息。为了增加SELECT语句检索结果的可读性,可以在SELECT关键字后增加用单引号引起来
12、的文字串,将检索数据连接成为一句话。第4章数据检索例例4-5 在查询结果中添加文字串:SELECT The phone number of,au_lname,Is,phone FROM authors 借助于字符串The phone number of和Is可以将检索结果组成一个完整的句子。检索结果如下:第4章数据检索(无列名)au_lname (无列名)phone-The phone number of White Is 408 496-7223The phone number of Green Is 415 986-7020The phone number of Carson Is 415
13、 548-7723The phone number of OLeary Is 408 286-2428The phone number of Straight Is 415 834-2919(所影响的行数为 23 行)第4章数据检索4.2.2数据运算数据运算检索结果中的数据可以是直接来自数据库表中的原始数据,也可以是由数据库表中的数据计算后得到的加工数据。数据运算是指对检索的数据进行各种运算,也就是说,可以在SELECT关键字后面列出的数据项上使用各种运算符和函数。这些运算符和函数包括算术运算符、数学函数、字符串函数、日期和时间函数、系统函数等。第4章数据检索1.算术表达式算术表达式大多数标准
14、的数学运算符都可以用来进行数据运算,如加(+)、减(-)、乘(*)和除(/)等。在算术表达式中引用的字段必须是数字类型的,如INT、SMALLINT、TINYINT、FLOAT、REAL、MONEY和SMALLMONEY。可以通过数据运算来改变检索结果表中的字段值。例如,如果想把表titles中的所有书的价格增加2元,可以使用下面的SELECT语句。第4章数据检索例例4-6 对titles表的每本书的价格增加2元的语句如下:SELECT price+2 FROM titles 当它执行时,每本书的价格都会增加2元。但是,通过这种途径所改变的数据不会存储于表titles中。对字段的运算只会影响执
15、行SELECT语句形成的结果表,而不会影响原始数据库表中的数据。第4章数据检索例例4-7 为了同时显示书的原始价格和涨价后的新价格,可以使用下面的SELECT语句,将原价以oldPrice为数据列名显示,新价钱以newPrice为数据列名显示。SELECT Title_id,Type,oldPrice=Price,newPrice=Price+2FROM titles检索结果为:第4章数据检索Title_id Type oldPrice newPrice-BU1032 business 19.9900 21.9900BU1111 business 11.9500 13.9500BU2075 b
16、usiness 2.9900 4.9900BU7832 business 19.9900 21.9900(所影响的行数为 18 行)第4章数据检索可以在一次数据检索中,对多个字段进行运算。例例4-8 通过把价格与销售量相乘,计算出每种书的总销售额。SELECT price*ytd_sales total revenueFROM titles 执行结果如下:第4章数据检索total revenue.81,859,0546,318,2055,978,7881,859,0540,619,68(所影响的行数为 18 行)第4章数据检索2.数值函数数值函数数值函数用于对算术表达式进行数学计算,并返回计算
17、结果。常用数值函数有:绝对值函数ABS、圆周率函数PI、正弦函数SIN、余弦函数COS、正切函数TAN、指数函数EXP等。第4章数据检索例例4-9算术表达式的计算如下:SELECT ABS(8),ABS(-8),ABS(0)运行结果如下:-8 8 0(所影响的行数为 1 行)第4章数据检索3.字符串函数字符串函数字符串由字母、符号和数字组成。字符串常量必须用单引号引起来。大多数字符串函数只能用于char和varchar数据类型,少数字符串函数也可用于binary和varbinary数据类型。字符串运算用“+”号将多个字符串连接在一起。第4章数据检索例例4-10字符串函数的使用:SELECT a
18、u_fname+au_lname author nameFROM authors 在这个例子中,把字段au_fname和字段au_lname粘贴在一起,中间用一个逗号隔开,并把查询结果的标题指定为author name。这个语句的执行结果是这样的:第4章数据检索author namesJohnson WhiteMarjorie GreenCheryl CarsonMichael OLearyDean Straight(所影响的行数为 23 行)第4章数据检索例例4-11大小写函数的使用如下:SELECT UPPER(basic),LOWER(BASIC)UPPER将字符串中的小写字母转变为大写
19、字母,LOWER将字符串中的大写字母转变为小写字母。本例的运行结果为:-BASIC basic(所影响的行数为 1 行)第4章数据检索例例4-12 REPLACE函数的使用如下:SELECT REPLACE(abc123g,123,def)REPLACE函数用第三个参数字符串代替第一个参数字符串中和第二个参数字符串相同的部分。本例的运行结果为:-abcdefg(所影响的行数为 1 行)第4章数据检索4.日期和时间函数日期和时间函数日期和时间函数是对日期和时间数据进行处理并返回处理结果。SQL Server 2000中提供的日期和时间函数如表4-1所示。第4章数据检索表表4-1 日期和时间函数日
20、期和时间函数函 数功 能YEAR(date)提取日期中的年MONTH(date)提取日期中的月DAY(date)提取日期中的日GETDATE()获取当前日期DATEADD(datepart,number,date)增加日期DATEDIFF(datepart,date1,date2)求时间间隔DATENAME(datepart,date)提取日期中的指定部分,返回数据类型为字符串DATEPART(datepart,date)提取日期中的指定部分,返回数据类型为整数第4章数据检索例例4-13 提取指定日期的年、月、日。SELECT DAY(03/12/1998)AS Day Number,MONT
21、H(03/12/1998)AS Month Number,YEAR(03/12/1998)AS Year NumberYEAR、MONTH 和DAY分别用于返回指定日期03/12/1998中表示年、月、日的数字。本例运行结果为第4章数据检索Day Number Month Number Year Number-12 3 1998(所影响的行数为 1 行)DATEADD函数返回指定日期date加上指定的时间间隔number产生的新日期,datepart用于指定时间间隔加在日期中的那一部分。第4章数据检索例例4-14 将pubs数据库中titles表中标题时间改为发布日期加上21天。SELECT
22、DATEADD(day,21,pubdate)AS timeframeFROM titles运行结果如下:timeframe-1991-07-03 00:00:00.0001991-06-30 00:00:00.0001991-07-21 00:00:00.000(所影响的行数为 18 行)第4章数据检索4.2.3选择数据行选择数据行检索数据库表中所有的数据行对数据库浏览和报表是有用的,对别的用处就不大了。在很多情况下,需要选择检索结果中某些有用的数据行。1.消除取值重复的数据行消除取值重复的数据行虽然数据库表中的数据行取值没有完全相同的两行,但是如果只取特定的数据列作为检索结果,在结果表中就
23、可能存在取值相同的行。在SELECT语句中,可以使用DISTINCT关键词,取消结果表中取值重复的数据行。第4章数据检索例例4-15 含重复行的查询语句如下:SELECT au_lname FROM authors检索结果如下所示:au_lname-RingerRinger(所影响的行数为 23 行)第4章数据检索从上述结果中可以看到,结果表中有两个取值为“Ringer”的数据行。下面,我们将检索程序改写一下,结果表中就只留下一个取值为“Ringer”的数据行了。例例4-16 不含重复行的查询如下:SELECT DISTINCT au_lname FROM authors检索结果如下所示:-R
24、inger(所影响的行数为 22 行)第4章数据检索2.查询满足单一条件的数据行查询满足单一条件的数据行借助WHERE子句可以设定选择条件,筛选满足条件的数据行并予以输出,不满足的数据行(记录)不予以输出。例例4-17 从表authors中取出所有名字为Ringer的作者的电话号码。SELECT phone FROM authors WHERE au_lname=Ringer 第4章数据检索结果如下所示:phone-801 826-0752801 826-0752(所影响的行数为 2 行)SQL提供了丰富的运算符号,可以在WHERE子句中形成不同种类的搜索条件。第4章数据检索1)比较测试搜索条
25、件在比较测试中,针对每条记录,SQL计算并比较由比较运算符连接在一起的两个表达式的值,判断该记录是否满足搜索条件。SQL提供了六种比较运算符:等于(=)、不等于()、小于()、小于等于()和大于等于(=)。第4章数据检索例例4-18 将价格小于等于10元的图书显示出来。SELECT Title_id,Type,PriceFROM titlesWHERE Price$5500第4章数据检索查询结果如下:title_id type advance-BU2075 business 10125.0000(所影响的行数为 1 行)第4章数据检索例例4-24 查询所有商业和心理学图书。SELECT tit
26、le_id,type,advanceFROM titlesWHERE type=business OR type=psychology查询结果如下:第4章数据检索title_id type advance-BU1032 business 5000.0000BU1111 business 5000.0000BU2075 business 10125.0000BU7832 business 5000.0000PS1372 psychology 7000.0000PS2091 psychology 2275.0000PS2106 psychology 6000.0000PS3333 psycholo
27、gy 2000.0000PS7777 psychology 4000.0000(所影响的行数为 9 行)第4章数据检索例例4-25 查询所有预付款不超过$5,500的图书。SELECT title_id,type,advanceFROM titlesWHERE NOT advance$5500查询结果如下:第4章数据检索title_id type advance-BU1032 business 5000.0000BU1111 business 5000.0000BU7832 business 5000.0000MC2222 mod_cook .0000PS2091 psychology 227
28、5.0000PS3333 psychology 2000.0000PS7777 psychology 4000.0000TC4203 trad_cook 4000.0000(所影响的行数为 8 行)第4章数据检索例例4-26 查询所有预付款不超过$5,500的商业和心理学图书。SELECT title_id,type,advanceFROM titlesWHERE(type=business OR type=psychology)AND NOT advance$5500查询结果如下:第4章数据检索title_id type advance-BU1032 business 5000.0000BU
29、1111 business 5000.0000BU7832 business 5000.0000PS2091 psychology 2275.0000PS3333 psychology 2000.0000PS7777 psychology 4000.0000(所影响的行数为 6 行)第4章数据检索4.2.4排序查询结果排序查询结果因为SQL表没有内在的顺序,如不进行特殊处理,数据检索结果表中的数据将会无序排列在一起。例如从表authors中取出字段au_lname。例例4-27 结果不排序的查询。SELECT au_lnameFROM authors本例从表authors中取出字段au_lna
30、me时,查询结果无序排列,显示成这样:第4章数据检索au_lname.WhiteGreenCarsonOLearyStraight(所影响的行数为23行)第4章数据检索看一列没有特定顺序的名字是很不方便的。如果把这些名字按字母顺序排列,读起来就会容易得多。通过使用ORDER BY子句,可以强制将检索结果数据排序。例例4-28 按作者名字字母的升序排列显示。SELECT au_lnameFROM authorsORDER BY au_lname执行结果如下所示:第4章数据检索au_lname-Bennet Blotchet-HallsCarsonDeFrancedel CastilloDullG
31、reenGreene(所影响的行数为 23 行)第4章数据检索ORDER BY子句默认按升序排列,如果想把查询结果按降序排列,需要使用关键字DESC。上例可以改写为:例例4-29 按作者名字字母的降序排列显示。SELECT au_lnameFROM authorsORDER BY au_lname DESCORDER BY子句中可以指定多个排序项。第一排序项是主排序项,其余为次要排序项。重要性程度依次降低。当同一级别排序项上两个数据行的数据相同时,按更次一级的排序项排序。第4章数据检索例例4-30 从表authors中取出所有作者的名字。将查询结果先按au_lname升序排列,对于相同的数据行
32、再按au_fname降序排列。SELECT au_lname,au_fname FROM authors ORDER BY au_lname,au_fname DESC 执行结果如下所示:第4章数据检索au_lname au_fnamePanteley SylviaRinger AnneRinger Albert(所影响的行数为23行)在这个表中,有两个作者有相同的名字Ringer。名为Albert Ringer的作者出现名为Anne Ringer的作者之后,这是因为姓Albert按字母顺序应排在姓Anne之前。第4章数据检索4.3高级数据检索技术高级数据检索技术除了基本数据检索技术之外,还可
33、以对检索到的数据进行合计、汇总等处理;除了从一个表中检索数据之外,还可以从多个表中检索数据;除了从表和视图中检索数据之外,还可以将检索数据结果作为中间过程,从中检索数据。这些都属于高级数据检索技术。第4章数据检索4.3.1合计数据合计数据为方便用户对表中的数据进行统计,增强检索功能,Microsoft SQL Server提供了多种类型的聚合函数,常用的有:用于统计数据行数的COUNT函数,用于计算平均值的AVG函数,用于查询最小值的MIN函数,用于查询最大值的MAX函数和用于求和的SUM函数。聚合函数用在SELECT子句中,返回值作为新的数据列出现在结果表中。除此之外,使用COMPUTE子句
34、也是经常用的方法。第4章数据检索1.COUNT函数函数COUNT函数用于统计数据行数。例例4-31 计算表authors中名字(last name)的数目。SELECT COUNT(au_lname)FROM authors 该例的返回值为23。如果表中有相同的名字,将会被多次计算。如果想知道名字为某个特定值的作者有多少个,你可以使用WHERE子句,如下例所示。第4章数据检索例例4-32 查询名字为Ringer的作者的数目。SELECT COUNT(au_lname)FROM authorsWHERE au_lname=Ringer该例的返回值为2,表示这个名字在表authors中出现了两次。
35、如果想知道有多少个不同名字的作者,可以通过使用关键字DISTINCT来得到该数目。第4章数据检索例例4-33 查询有多少个不同名字的作者。SELECT COUNT(DISTINCT au_lname)FROM authors 该例的返回值为22。名字Ringer虽然出现了不止一次,但它只被计算一次。关键字DISTINCT 决定了只有互不相同的值才被计算。2.AVG函数和函数和SUM函数函数使用AVG函数可以计算出某个字段中所有数值的平均数。使用SUM函数可以计算出某个字段中所有数值的总和。第4章数据检索例例4-34 计算所有商业类书籍的平均预付款及本年度迄今为止的销售额。SELECT AVG(
36、advance),SUM(ytd_sales)FROM titlesWHERE type=business执行结果如下:-6281.2500 30788(所影响的行数为 1 行)第4章数据检索3.MAX函数和函数和MIN函数函数 MAX函数用于查找数据列中的最大数值,MIN函数用于查找数据列中的最小数值。例例4-35 计算年度最高销售额和年度最低销售额。SELECT MAX(ytd_sales),MIN(ytd_sales)FROM titles执行结果如下:-22246 111(所影响的行数为 1 行)第4章数据检索4.COMPUTE子句子句COMPUTE所生成的汇总值在查询结果中显示为分离
37、的结果集,包括 COMPUTE 子句的查询的结果类似于控制中断报表,即汇总值由指定的组(或称中断)控制的报表。可以为各组生成汇总值,也可以对同一组计算多个聚合函数。第4章数据检索例例4-36 计算titles 表中 price 及 advance 的求和总计。SELECT type,price,advanceFROM titlesORDER BY typeCOMPUTE SUM(price),SUM(advance)检索结果为:第4章数据检索type price advance -business 19.9900 5000.0000business 11.9500 5000.0000busin
38、ess 2.9900 10125.0000business 19.9900 5000.0000mod_cook 19.9900 .0000mod_cook 2.9900 15000.0000第4章数据检索popular_comp 22.9500 7000.0000popular_comp 20.0000 8000.0000popular_comp NULL NULL sum sum=236.2600 95400.0000第4章数据检索当COMPUTE 带有可选的BY子句时,符合SELECT条件的每个组都有两个结果集:每个组的第一个结果集是明细行集,其中包含该组的选择列表信息。每个组的第二个结果
39、集有一行,其中包含该组的 COMPUTE 子句中所指定的聚合函数的小计。第4章数据检索例例4-37 在COMPUTE子句中加入可选的BY关键字,以生成每个组的小计。SELECT type,price,advanceFROM titlesORDER BY typeCOMPUTE SUM(price),SUM(advance)BY type检索结果为:第4章数据检索type price advance -mod_cook 19.9900 .0000mod_cook 2.9900 15000.0000 sum =22.9800 sum =15000.0000第4章数据检索type price adv
40、ance -popular_comp 22.9500 7000.0000popular_comp 20.0000 8000.0000popular_comp NULL NULL sum =42.9500 sum =15000.0000第4章数据检索4.3.2分组检索数据分组检索数据如果没有对数据分组,合计函数只能对整个表产生一个汇总数据。如果要细化合计函数作用的对象,对表中数据分门别类地进行汇总统计,就要对数据库表进行分组检索。使用GROUP BY子句可以对数据库表中的数据进行分组。第4章数据检索例例4-38 将表titles中的数据按type字段进行分组,然后对各组分别计算预付款均值和年度销
41、售总额。SELECT type,AVG(advance)avg_advance,SUM(ytd_sales)sum_ytd_salesFROM titlesGROUP BY type检索结果为:第4章数据检索type avg_advance sum_ytd_sales-business 6281.2500 30788mod_cook 7500.0000 24278popular_comp 7500.0000 12875psychology 4255.0000 9939trad_cook 6333.3333 19566UNDECIDED NULL NULL(所影响的行数为 6 行)第4章数据检索
42、在GROUP BY子句中按某一列或某几列的数值分组,数值相等的分为一组。GROUP BY子句和HAVING子句配合使用,可以滤出不满足HAVING子句中指定条件的组。HAVING子句和WHERE子句的不同之处在于:WHERE子句过滤数据库表中的数据行,HAVING子句过滤分好的组。第4章数据检索例例4-39 显示平均预付款大于7000元的分组汇总数据。SELECT type,AVG(advance)avg_advance,SUM(ytd_sales)sum_ytd_salesFROM titlesGROUP BY typeHAVING AVG(advance)7000检索结果为:第4章数据检索
43、type avg_advance sum_ytd_sales-mod_cook 7500.0000 24278popular_comp 7500.0000 12875(所影响的行数为 2 行)第4章数据检索例例4-40 先选择出预付款大于7000元的数据行,然后按类型分组。SELECT type,AVG(advance)avg_advance,SUM(ytd_sales)sum_ytd_salesFROM titlesWHERE advance7000GROUP BY type检索结果如下:第4章数据检索 type avg_advance sum_ytd_sales-business 1012
44、5.0000 18722mod_cook 15000.0000 22246popular_comp 8000.0000 4095trad_cook 8000.0000 4095(所影响的行数为 4 行)第4章数据检索4.3.3连接检索技术连接检索技术前面所提到的数据检索只限于从一个表中提取数据,在实际应用中,经常会遇到从多个表中提取数据的情况。使用连接检索技术,可将多个表中的数据行按连接条件组合成一个表,然后进行查询。这样就可以在一个SELECT语句中检索到多个表中的数据。第4章数据检索1.一个简单的连接检索例子一个简单的连接检索例子下面先来看一个简单的连接检索例子。在这个例子中,要从表aut
45、hors中取出所有的作者名字,从表titles中取出所有的书名。将所涉及到的两个表authors和titles写进FROM子句。例例4-41 查询每个作者的名字和所有的书名。SELECT au_lname,title FROM authors,titles检索结果为:第4章数据检索au_lname title-Bennet But Is It User Friendly?Blotchet-Halls But Is It User Friendly?Carson But Is It User Friendly?DeFrance But Is It User Friendly?(所影响的行数为 4
46、14 行)第4章数据检索查看检索结果,会发现作者的名字并没有和他们所著的书相匹配,而是出现了作者名字和书名的所有可能的组合。这是因为没有指明两个表之间的关系,服务器只能从两个表中数据行所有可能组合中提取数据。要从多个表中筛选出有意义的数据组合,就需要建立表与表之间的连接关系。用来连接两个表之间的条件称为连接条件,要将其写入WHERE子句。第4章数据检索表authors中有一个名为au_id的字段,包含每个作者的唯一标识。表titles中有一个名为title_id的字段,包含每个书名的唯一标识。如果能在字段au_id和字段title_id 之间建立一个关系,就可以关联这两个表。数据库pubs中有
47、一个名为titleauthor的表,包括auid和title_id两个字段,用以把表titles和表authors关联在一起。例4-42的SELECT语句使用了这三个表,并得到正确的结果。第4章数据检索例例4-42 查询每个作者的名字和该作者写的书名。SELECT au_name,title FROM authors,titles,titleauthor WHERE authors.au_id=titleauthor.au_id AND titles.title_id=titleauthor.title_id 检索结果为:第4章数据检索 au_lname title-Carson But Is
48、 It User Friendly?MacFeather Computer Phobic AND Non-Phobic Individuals:Behavior VariationsKarsen Computer Phobic AND Non-Phobic Individuals:Behavior VariationsOLeary Cooking with Computers:Surreptitious Balance Sheets(所影响的行数为 25 行)第4章数据检索在上述例子中,为了区别表authors和表titles中相同的字段名au_id,每个字段名前面都加上了表名前缀。名为aut
49、hors.au_id的字段属于表authors,名为titleauthor.au_id的字段属于表titleauthor,这样,两者便不会混淆。如果字段名在所使用的表中是唯一的,则表名前缀可以省略。第4章数据检索连接不仅是两个表之间的连接,还可以是一个表和其自身的连接,称为自身连接。SELECT语句可通过为表指定别名来提高程序的可读性。在指派表的别名时,可以使用也可以不使用AS关键字:table_name AS table aliastable_name table_alias 在下例中,为publishers指派了别名p。第4章数据检索例例4-43 为表指派别名的查询。USE pubsSEL
50、ECT p.pub_id,p.pub_nameFROM publishers AS p如果为表指派了别名,那么在语句中对该表的所有显式引用都必须使用别名,而不能使用表名。例如,下列 SELECT 语句将产生语法错误,因为该语句在已指派别名的情况下又使用了表名:SELECT Customers.CustomerID,/*Illegal reference to Customers.*/Cst.FirstName,Cst.LastNameFROM Northwind.dbo.Customers AS Cst第4章数据检索2.连接类型连接类型连接类型可分为内连接、外连接和交叉连接三种。(1)内连接是