1 / 126

第 5 章 关系数据库标准语言 SQL

第 5 章 关系数据库标准语言 SQL. SQL 是 Structured Query Language 的缩写,即结构化查询语言。它是关系数据库的标准语言。查询是 SQL 语言的重要组成部分, SQL 还包含数据定义、数据操作和数据控制功能等内容。 SQL 已经成为关系数据库的标准数据语言,所以现在所有的关系数据库管理系统都支持 SQL 。掌握 SQL 语法可以更加灵活地建立查询和视图。. 5.1 SQL 简介.

nadda
Download Presentation

第 5 章 关系数据库标准语言 SQL

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第5章 关系数据库标准语言SQL • SQL是Structured Query Language的缩写,即结构化查询语言。它是关系数据库的标准语言。查询是SQL语言的重要组成部分,SQL还包含数据定义、数据操作和数据控制功能等内容。SQL已经成为关系数据库的标准数据语言,所以现在所有的关系数据库管理系统都支持SQL。掌握SQL语法可以更加灵活地建立查询和视图。

  2. 5.1 SQL简介 • SQL语言来源于20世纪70年代IBM的一个被称为SEQUEL(Structured English Query Language)的研究项目。20世纪80年代,SQL由ANSI进行了标准化,它包括了定义和操作数据的指令。由于它具有功能丰富、使用方式灵活、语言简洁易学等突出特点,在计算机界深受广大用户欢迎,许多数据库生产厂家都相继推出各自支持SQL标准。1998年4月,ISO提出了具有完整性特征的SQL,并将其定为国际标准,推荐它为标准关系数据库语言。1990年,我国也颁布了《信息处理系统数据库语言SQL》,将其定为中国国家标准。

  3. 5.1.1 SQL语言的主要特点 (1)一体化语言 (2)高度非过程化 (3)语言简洁 (4)统一的语法结构对待不同的工作方式

  4. 5.1.2 SQL语句的执行 SQL语句可以在命令窗口中执行,也可以作为查询或视图(的内容)被使用,还可以在程序文件被执行。 表5.1 SQL命令动词 —————————————————————— SQL功能 命令动词 ———————————————————— 数据查询 SELECT 数据定义 CREATE、DROP、ALTER 数据操作 INSERT、UPDATE、DELETE 数据控制 GRANT、REVOKE ——————————————————————

  5. 5.2 查询功能 • 数据库中最常见的操作是数据查询,也是SQL的核心。

  6. 5.2.1 SQL语法 • SQL给出了简单而又丰富的查询语句形式,SQL的查询命令也称作SELECT命令,它的基本形式由SELECT-FROM-WHERE查询块组成,多个查询块可以嵌套执行。 • 格式: • SELECT [ALL|DISTINCT][ TOP〈表达式〉 ] [ 〈别名〉 ] 〈Select表达式〉 [AS 〈列名〉 ][, [ 〈别名〉 ] 〈Select表达式〉 [AS 〈列名〉 ]…] FORM[ 〈数据库名〉 !] 〈表名〉 [[AS]Local_Alias] [[INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] JOIN[ 〈数据库名〉 !] 〈表名〉 [[AS]Local_Alias][ON〈联接条件〉 ]] [INTO 〈查询结果〉 |TO FILE 〈文件名〉 [ADDITIVE] | TO PRINTER [PROMPT] | TO SCREEN] [PREFERENCE PreferenceName][NOCONSOLE][PLAIN][NOWAIT] [WHERE 〈联接条件1〉 [AND 〈联接条件2〉…][AND | OR 〈筛选条件〉 …]] [GROUP BY 〈组表达式〉 ][, 〈组表达式〉 …]] [HAVING ]〈筛选条件〉 ] [UNION [ALL] 〈SELECT命令〉 ] [ORDER BY 〈关键字表达式〉 [ASC |DESC] [, 〈关键字表达式〉 [ASC |DESC]…]] • 说明:SELECT-SQL命令的格式包括三个基本子句:SELECT子句、FROM子句、WHERE子句,还包括操作子句:ORDER子句、GROUP子句、UNION子句以及其他一些选项。

  7. SELECT 查询项目 FROM 数据库源 WHERE 查询条件 GROUP BY 分组表达式 HAVING 筛选条件 ORDER BY 排序关键字表达式

  8. 1.SELECT子句 • SELECT子句用来指定查询结果中的数据。其中: • ALL选项:表示选出的记录中包括重复记录,这时缺省值;DISTINCT则表示选出的记录中不包括重复记录。 • TOP〈表达式〉选项:表示在符合条件的记录中,选取指定数量或百分比(〈表达式〉)记录。[〈别名〉]〈Select表达式〉[AS〈列名〉]选项中的别名是字段所在的表名;〈Select表达式〉,可以是字段名或字段表达式;〈列名〉用于指定输出时使用的列标题,可以不同于字段名。 • 〈Select表达式〉用一个*号来表示时,指定所有的字段。

  9. 2.FROM子句 • 用于指定查询的表与联接类型。其中: • JOIN关键字用于联接其左右两个〈表名〉所指定的表。INNER | LEFT[OUTER] | RIGHT[OUTER] | FULL[OUTER]选项,指定两表联接时的联接类型,联接类型有4种,如表5.2所示。其中的OUTER选项,表示外部联接,即允许满足联接条件的记录,又允许不满足联接条件的记录。若省略OUTER选项,效果不变。

  10. 3.WHERE子句 • 用来指定查询的条件。其中的 〈联接条件〉 指定一个字段,该字段连接FROM子句中的表。 • 如果查询中包含不止一个表,就应该为第一个表后的每一个表指定连接条件。

  11. 4.GROUP BY子句 对查询结果按〈组表达式〉值分组,常用于分组统计。

  12. 5. HAVING子句 当含有GROUP BY子句时,HAVING子句可用作记录查询的限制条件;无GROUP BY 子句时,HAVING子句的作用如同 WHERE子句。

  13. 6. ORDER BY子句 指定查询结查中记录按〈关键字表达式〉排序,默认升序。选项ASC表示升序,DESE表示降序。

  14. 7.其他子句和选项 • UNION子句:可以用UNION子句嵌入另一个SELECT-SQL命令,使这两个命令的查询结果合并输,但输出字段的类型和宽度必须一致。UNION子句默认组合结果中排除重复行,使用ALL,则允许包含重复行。 • SELECT查询命令的使用非常灵活,用它可以构造各种各样的查询。本章将通过大量的实例来介绍SELECT命令的使用方法。

  15. 5.2.2 简单查询 简单查询只含有基本子句,可有简单的查询条件。 【5.1】在zgda表中,检索所有字段。 SELECT * FROM zgda

  16. 5.2.2 简单查询 【5.2】在zggz表中,检索实发工资大于2000元的记录。 SELECT 编号,姓名,实发工资 FROM zggz WHERE 实发工资>2000

  17. 5.2.2 简单查询 【5.3】在zgda表中,检索所有职称名称。 SELECT DISTINCT 职称 FROM zgda 【5.4】在zgda表中,检索职称是助教的记录。 SELECT 编号,姓名,职称 FROM zgda WHERE 职称="助教"

  18. 5.2.2 简单查询 【5.5】在zggz表中,检索实发工资小于1000大于1800元的记录。 SELECT 编号,姓名,实发工资 FROM zggz WHERE 实发工资>1000 AND 实发工资<1800

  19. 5.2.3 几个特殊运算符 • 在SQL语句中,WHERE子句后面的联接条件,除了可以使用VFP语言中的关系表达式以及逻辑表达外,还可以使用几个特殊运算符: (1)[NOT]IN:表示[不]在…之中。 (2)[NOT]BETWEEN…AND…:表示[不]在…之间。 (3)[NOT]LIKE:表示[不]与…匹配。

  20. 5.2.3 几个特殊运算符 下面以实例来说明此用法。 说明: (1)NOT运算符来设计否定条件。 (2)LIKE运算符提供两种字符串匹配方式,一种是使用下划线符号“_”,匹配一个和任意字符,另一种是使用百分号“%”,匹配0个或多个任意字符。 (3)IN运算符,格式为IN(常量1,常量2,…)。含义为查找和常量相等的值。

  21. 5.2.3 几个特殊运算符 【5.6】在zgda表中,检索性别是男的记录。 SELECT DISTINCT 编号,姓名,性别 FROM zgda WHERE 性别 LIKE "男" 可以使用NOT运算符来设计否定条件,检索性别不是男的记录。 SELECT DISTINCT 编号,姓名,性别 FROM zgda WHERE NOT(性别 LIKE "男")

  22. 5.2.3 几个特殊运算符 【5.7】在zgda表中,检索所有姓刘的记录。 SELECT 编号,姓名 FROM zgda WHERE 姓名 LIKE "刘%"

  23. 5.2.3 几个特殊运算符 【5.8】在zgda表中,检索所有姓陈和姜的记录。 SELECT 编号,姓名 FROM zgda WHERE 姓名 IN("陈","姜") 上式可以改为VFP条件,执行结果是一样的。 SELECT 编号,姓名 FROM zgda WHERE 姓名="陈" OR 姓名="姜"

  24. 5.2.4 简单的联接查询 联接是关系的基本操作之一,联接查询是一种基于多个关系的查询。 【5.9】在zgda表和zggz表中,检索实发工资大于2000元的记录。 SELECT zgda.编号,zgda.姓名,zggz.实发工资 FROM zgda,zggz WHERE (实发工资>2000) AND (zgda.编号=zggz.编号) zgda.编号=zggz.编号 &&编号是联接的条件

  25. 5.2.4 简单的联接查询 【5.10】在zgda表和zggz表中,检索职称是讲师, 并且实发工资大于1900元的记录 SELECT zgda.编号,zgda.姓名,zgda.职称,zggz.实发工资 FROM zgda,zggz WHERE (职称="讲师") AND (实发工资>1900) AND (zgda.编号=zggz.编号)

  26. 5.2.5 嵌套查询 • 为了讨论嵌套查询,在此引入一个订货管理数据库,此数据库涉及4个表(4 个关系),即仓库表、职工表、订购单表、供应商表,4个表的内容见教材 P.90。

  27. 5.2.5 嵌套查询 • 【5.11】在仓库表和职工表中,检索哪些城市至少有一个仓库的职工工资为1250元 • SELECT 城市 FROM 仓库 WHERE 仓库号 IN (SELECT 仓库号 FROM 职工 WHERE 工资=1250) • 在这个命令中含有两个SELECT-FROM-WHERE查询块,即内层查询块和外层查询块,内层查询块 检索到的仓库号值是WH1和WH2, 这里IN相当于集合运算符∈。这样就可写出等价的命令: • SELECT 城市 FROM 仓库 WHERE 仓库号 IN("WH1", "WH2")

  28. 5.2.5 嵌套查询 • 【5.12】在仓库表和职工表中,检索所有职工的工资都多于为1210元的仓库信息。 • SELECT * FROM 仓库 WHERE 仓库号 NOT IN(SELECT 仓库号FROM职工 WHERE工资 <=1210)

  29. 5.2.5 嵌套查询 • 内层SELECT-FROM-WHERE查询块指出所有职工的工资少于或等于1210元的仓库的仓库号值的集合,在这里该集合只有一个值“WH1”;然后从仓库关系中检索元组的仓库号属性值不在该集合中的每个元组。刚才的检索出现了错误,尽管在“武汉”的“WH4”仓库还没有职工,但该仓库的信息也被检索出来了。所以必须认真分析检索要求,写出正确的SQL命令。如果要求排除那些还没有职工的仓库,检索要求可以叙述为:检索所有职工的工资都多于1210元的仓库的信息,并且该仓库至少要有一名职工。这样描述就很清楚了,因为我们对没有职工的仓库不感兴趣。 • SELECT * FROM 仓库 WHERE 仓库号 NOT IN (SELECT 仓库号 FROM 职工 WHERE 工资<=1210) AND 仓库号 IN(SELECT 仓库号 FROM 职工) • 这样内层是两个并列的查询,在结果中将不包含没有职工的仓库信息。

  30. 5.2.5 嵌套查询 • 【5.13】检索出和职工E4挣同样工资的所有职工。 • SELECT 职工号 FROM 职工 WHERE 工资= (SELECT 工资 FROM 职工 WHERE 职工号="E4")

  31. 5.2.5 嵌套查询 • 【5.14】检索出工资在1220元到1240元范围内的职工信息。这个查询的条件值是在什么范围之内,显然可以用BETWEEN…AND…,为此有如下查询语句: • SELECT * FROM 职工 WHERE工资 BETWEEN 1220 AND 1240 这里BETWEEN…AND…意思是在“…和…之间”,这个查询的条件等价于: (工资>=1220) AND (工资<=1240) • 使用BETWEEN…AND…表达条件更清晰、更简洁。假如找出工资不在1220元和1240元之间的全部职工信息,可以用命令: • SELECT * FROM 职工 WHERE工资 NOT BETWEEN 1220 AND 1240

  32. 5.2.5 嵌套查询 • 【5.15】在供应商表中,检索出全部公司的信息,不要工厂或其他供应商的信息。这是一个字符串匹配的查询,显然应该使用LIKE运算符: • SELECT * FROM 供应商 WHERE 供应商名 LIKE "%公司" • 这里的LIKE是字符串匹配运算符,通配符“%”表示0个或多个字符,另外还有一个通配符“-”表示一个字符。

  33. 5.2.5 嵌套查询 【5.16】在供应商表中,找出不在北京的全部供应商的信息。 SELECT * FROM 供应商 WHERE 地址!="北京" 在SQL中,“不等于”用“!=”表示。另外还可以用否定运算符NOT写出等价命令: SELECT * FROM 供应商 WHERE NOT(地址="北京") NOT的应用范围很广,比如,可以有NOT IN、NOT BETWEEN等。

  34. 例.查询与刘晨同一个系的学生的情况 SELECT Sno,Sname,Sdept FROM Student WHERE Sdept IN (SELECT Sdept FROM Student WHERE Sname= ‘刘晨 ’);

  35. ① 确定“刘晨”所在系名 SELECT Sdept FROM Student WHERE Sname= ‘刘晨 ’; Sno Sname Sdept 95001 刘晨 IS 95002 张三 BA 95004 李四 cs 95004 张立 IS 结果为: Sdept IS

  36. ② 查找所有在IS系学习的学生。 SELECT Sno,Sname,Sdept FROM Student WHERE Sdept= ‘ IS ’; Sno Sname Sdept 95001 刘晨 IS 95002 张三 BA 95004 李四 cs 95004 张立 IS 结果为: Sno Sname Sdept 张立 IS 95001 刘晨 IS 95004 张立 IS

  37. 5.2.6 排序 SQL中排序操作使用ORDER BY子句。 格式:ORDER BY 〈关键字表达式1〉 [ASC | DESC][, 〈关键字表达式2〉 [ASC | DESC]…] 说明:ASC为升序(默认为升序),DESC为降序。允许按一列或多列排序。

  38. 5.2.6 排序 【5.17】在职工表中,按职工的工资值升序检索出全部职工的信息。 SELECT * FROM 职工 ORDER BY 工资 这里ORDER BY是排序子句,如果需要将结果按降序排列,只要加上DESC。 SELECT * FROM 职工 ORDER BY 工资 DESC

  39. 5.2.6 排序 【5.18】在职工表中,先按仓库号排序,再按工资排序,并输出全部职工信息。 SELECT * FROM 职工 ORDER BY 仓库号,工资 说明:ORDER BY是对最终的查询结果进行排序,不可以在子查询中使用该短语。

  40. 5.2.7 简单的计算查询 SQL语言是完备的,也就是说,只要数据是按关系方式存入数据库的,就能构造合适的SQL命令把它检索出来。事实上,SQL不仅具有一般的检索能力,而且还有计算方式的检索,比如检索职工的平均工资、检索某个仓库中职工的最高工资值等。用于计算检索的函数有: (1)COUNT—计数 (2)SUM—求和 (3)AVG—计算平均值 (4)MAX—求最大值 (5)MIN—求最小值 这些函数可以用在SELECT短语中对查询结果进行计算。

  41. 5.2.7 简单的计算查询 【5.19】在供应商表中,找出供应商所在地的数目。 SELECT COUNT (DISTINCT 地址) FROM 供应商 说明,除非对关系中的元组个数进行计数,一般应用COUNT函数应该使用DISTINCT。例如: SELECT COUNT(*) FROM 供应商 将给出供应商关系中的记录数是6个。

  42. 5.2.7 简单的计算查询 【5.20】在职工表中,求支付的工资总数。 SELECT SUM(工资) FROM 职工 结果是职工关系中的工资值的总和,它并不管是否有重复值。这时若使用命令: SELECT SUM(DISTINCT 工资) FROM 职工 将得出错误的结果。原因是DISTINCT命令去掉重复值1250。

  43. 5.2.7 简单的计算查询 【5.21】在职工表和仓库表中,求北京和上海的仓库职工的工资总和。 SELECT SUM(工资) FROM 职工 WHERE 仓库号 IN (SELECT 仓库号 FROM 仓库 WHERE 城市="北京" OR 城市="上海")

  44. 5.2.7 简单的计算查询 [5.22] 在仓库表和职工表中,求所有职工的工资都多于1210元的仓库的平均面积。 SELECT AVG(面积) FROM 仓库 WHERE 仓库号 NOT IN (SELECT 仓库号 FROM 职工 WHERE 工资<=1210) 这里要注意,以上结果的运算包含了尚没有职工的WH4仓库。如果要排除没有职工的仓库,以上语句应该改为: SELECT AVG(面积) FROM 仓库 WHERE 仓库号 NOT IN (SELECT 仓库号 FROM 职工 WHERE 工资<=1210) AND仓库号 IN (SELECT仓库号 FROM 职工)

  45. 5.2.7 简单的计算查询 【5.23】在职工表中,求在WH2仓库工作的职工的最高工资值。 SELECT MAX(工资) FROM 职工 WHERE 仓库号="WH2" 与MAX函数相对应的是MIN函数(求最小值)。比如,求最低工资值可以有如下命令: SELECT MIN(工资) FROM 职工 WHERE 仓库号="WH2"

  46. 5.2.8 分组与计算查询 上面几个例子是对整个关系的计算查询,而利用GROUP BY子句可以进行分组计算查询,使用得更加广泛。格式:GROUP BY 〈分组字段名〉[〈分组字段名〉…][HAVING〈过滤条件〉]可以按一列或多列分组,还可以用HAVING进一步限定分组的条件。下面是几个分组计算查询的例子。

  47. 5.2.8 分组与计算查询 【5.24】在职工表中,求每个仓库的职工的平均工资。 SELECT 仓库号,AVG(工资) FROM 职工 GROUP BY 仓库号 在这个查询中,首先按仓库号属性进行分组,然后再计算每个仓库的平均工资。GROUP BY子句一般跟在WHERE子句之后,没有WHERE子句时,跟在FROM子句之后。另外,还可以根据多个属性进行分组。在分组查询时,有时要求分组满足某个条件时才检索,这时可以用HAVING子句来限定分组。

  48. 5.2.8 分组与计算查询 【5.25】在职工表中,求至少有两个职工的每个仓库的平均工资。 SELECT 仓库号,COUNT(*),AVG(工资) FROM 职工 GROUP BY 仓库号 HAVING COUNT(*)>=2 • HAVING子句总是跟在GROUP BY 子句之后,不可以单独使用。HAVING子句和WHERE 子句不矛盾,在查询中是先用WHERE子句限定元组,然后再进行分组,最后再用HAVING子句限定分组。 • 说明:HAVING子句和WHERE子句的区别:WHERE子句是用来指定表中各行所应满足的条件,而HAVING子句是用来指定每一分组所满足的条件,只有满足HAVING条件的那些组才能在结果中被显示。

  49. 5.2.9 别名的使用 在联接操作中,经常需要使用关系名作前缀,有时这样显得很麻烦。因此,SQL允许在FROM短语中为关系名定义别名。 • 格式:〈关系名〉〈别名〉 • 例如:如下的联接语句是一个基于4个关系的联接查询,其中必须使用关系名作前缀: SELECT 供应商名 FROM 供应商,订购单,职工,仓库 WHERE 地址="北京" AND 城市="北京" AND 供应商.供应商号=订购单.供应商号 AND 订购单.职工=职工.职工号 AND 职工.仓库号=仓库.仓库号

  50. 5.2.9 别名的使用 在上面的查询中,如果使用别名就会简单一些,如下是使用了别名的同样的联接查询语句: SELECT 供应商名 FROM 供应商 S,订购单 P,职工 E,仓库 W WHERE 地址="北京"AND 城市="北京" AND S.供应商号=P.供应商号 AND P.职工号=E.职工号 AND E.仓库号=W.仓库号 • FROM 供应商 S,订购单 P,职工 E,仓库 W,用S、P、E和W分别代表供应商表、订购单表、职工表和仓库表。 • 说明:在嵌套的SQL子句中不能使用外层定义的别名。

More Related