390 likes | 572 Views
第五章 关系数据库 SQL 语言. 本 章 内 容. §5.1 SQL 概述 §5.2 查询语句 SELECT-SQL §5.2.1 单表查询 §5.2.2 多表查询 §5.2.3 嵌套查询. §5.2.4 自联查询 §5.2.5 集合的并运算 §5.3 其他 SQL 命令 §5.3.1 定义功能的 SQL 语句 §5.3.2 操作功能的 SQL 语句. §5.1 SQL 概述. 1 .结构化查询语言 SQL 简介
E N D
第五章 关系数据库SQL语言 本 章 内 容 §5.1 SQL概述 §5.2 查询语句SELECT-SQL §5.2.1 单表查询 §5.2.2 多表查询 §5.2.3 嵌套查询 §5.2.4 自联查询 §5.2.5 集合的并运算 §5.3 其他SQL命令 §5.3.1 定义功能的SQL语句 §5.3.2 操作功能的SQL语句
§5.1SQL概述 1.结构化查询语言SQL简介 结构化查询语言SQL(Structured Query Language)是关系数据库的标准语言。目前包括VFP在内的数据库开发软件都支持SQL语言。 2.SQL语言的主要特点 (1)SQL是一种一体化的语言,它包括数据定义、数据查询、数据操纵和数据控制功能,可以完成数据库的全部操作。 (2)SQL是一种非过程化的语言,用户在编写程序时,只要指出“干什么”,而不必一步步告诉计算机“怎么干”,SQL将自动完成全部操作。
(3)SQL语言非常简洁且功能很强,一共只用为数不多的几条命令:(3)SQL语言非常简洁且功能很强,一共只用为数不多的几条命令: 1)查询数据命令SELECT-SQL(它是最重要的一条SQL命令) 2)创建新表命令CREATE TABLE-SQL 3)修改表结构命令ALTER TABLE -SQL 4)追加记录命令INSERT-SQL 5)逻辑删除记录命令DELETE-SQL 6)更新记录数据命令UPDATE-SQL 7)创建视图命令CREATE VIEW-SQL (4)SQL语言既可以作为单命令以交互方式使用,也可以作为语句写入程序中以程序方式使用。
§5.2 查询语句SELECT-SQL 1.SELECT-SQL命令的基本格式 SELECT [ALL|DISTINCT][TOP nExpr [PERCENT]] [Alias.]Select_Item [AS Column_name][,[Alias.]Select_Item [AS Column_name]…] FROM [DataName!]TableName [[AS] Local_Alias] [,[DataName!]TableName [[AS] Local_Alias]…] [INNER|LEFT[OUTER]|RIGHT[OUTER]|FULL[OUTER] JOIN [DataName!]TableName [[AS] Local_Alias] [ON JoinCondition]…] [WHERE JoinCondition [AND JoinCondition…] [AND|OR FilterCondition [AND|OR FilterCondition…]]] [ORDER BY Order_Item [ASC|DESC][,Order_Item [ASC|DESC]…]] [GROUP BY GroupColumn [,GroupColumn…] [HAVING FilterCondition]] [TO SCREEN|FILE FileName [ADDITIVE]|PRINTER [PROMPT]] [INTO TABLE TableName|CURSOR CursorName|ARRAY ArrayName]
§5.2.1 单表查询 SELECT-SQL命令的主体结构是: SELECT <输出列名表>FROM <表名>WHERE <查询条件> 单表查询是指查询结果和查询条件所涉及的字段都在同一个表中。在使用SELECT-SQL命令时,FROM子句中只出现一个表名。 1.无条件查询 命令格式:SELECT <列名表> FROM <表名> 功能:在指定的表中查询指定的字段内容。 说明:若<列名表>使用通配符 *,代表所有字段。
1)查询指定表中所有记录的指定字段。 【例5-1】在“职工业绩”数据库的Zgjk.dbf表中,查询所有职工的职工号、姓名和部门的信息。 在命令窗口中键入: SELECT 职工号,姓名,部门 FROM Zgjk&&查询结果默认浏览窗口 2)查询指定表中所有记录的所有字段。 【例5-2】在Zgjk.dbf表中,查询所有职工的详细信息,并将查询结果直接显示于VFP主窗口。 在命令窗口中键入: SELECT * FROM Zgjk TO SCREEN
3)查询指定表中所有记录的统计值。 SQL语言具有计算查询功能,允许使用统计函数构 SELECT命令中可用的标准函数见下表。
【例5-3】在Zgjk.dbf表中,查询所有职工的最高基本工资、最低基本工资和平均基本工资,并要求查询结果的列标题分别为:最高基本工资、最低基本工资和平均基本工资。【例5-3】在Zgjk.dbf表中,查询所有职工的最高基本工资、最低基本工资和平均基本工资,并要求查询结果的列标题分别为:最高基本工资、最低基本工资和平均基本工资。 在命令窗口中键入: SELECT MAX(基本工资) AS 最高基本工资 , ; MIN(基本工资) AS 最低基本工资 , ; AVG(基本工资) AS 平均基本工资 ; FROM Zgjk 注意:SQL命令的续行号是半角分号;查询结果的列名可用AS子句指定,且AS可省略。 【例5-4】在Zgjk.dbf表中,查询所有职工的职工号、姓名和年龄。 在命令窗口中键入: SELECT 职工号,姓名,YEAR(DATE())-YEAR(出生日期) AS 年龄 FROM Zgjk
2.条件查询 格式:SELECT <列名表> FROM <表名> WHERE <条件> 功能:在指定的表中查询满足WHERE条件子句的记录。 说明:在构造条件表达式时,除了可以使用比较运算 符和逻辑运算符之外,还可以使用SQL专用运算符: BETWEEN … AND …和… LIKE …。 BETWEEN … AND … 运算符的含意: WHERE 基本工资 BETWEEN 200 AND 300 等效于:WHERE 基本工资>=200 AND 基本工资<=300。 … LIKE …运算符的含意: WHERE 姓名 LIKE "刘%“ 等效于:WHERE LEFT(姓名,2)="刘"
(1)简单条件查询 【例5-5】在Zgjk.dbf表中,查询基本工资在1000元以上(含1000元)职工的姓名和部门(要求不重复显示)。 在命令窗口中键入: SELECT DISTINCT 姓名,部门,基本工资 FROM Zgjk WHERE 基本工资>=1000 (2)复合条件查询 【例5-6】在Zgjk.dbf表中,查询家电部门已婚的职工的信息。 在命令窗口中键入: SELECT * FROM Zgjk WHERE 部门="家电" AND 婚否
(3)模糊条件查询 在WHERE子句中,可使用LIKE运算符对字符型数据进行模糊查询。带有LIKE的WHERE子句格式如下: WHERE LIKE "<字符串通配式>" 说明:通配符_(半角的下划线)代表该位置任意一个字符或汉字;通配符%(半角)代表该位置若干个字符或汉字。 【例5-7】在Zgjk.dbf表中,查询姓“李”的职工的信息。 在命令窗口中键入: SELECT * FROM Zgjk WHERE 姓名 LIKE "李%“ 此例子也可以使用字符非精确比较和函数来实现,例如: SELECT * FROM Zgjk WHERE 姓名="李" SELECT * FROM Zgjk WHERE LEFT(姓名,2)="李" SELECT * FROM Zgjk WHERE AT("李",姓名)=1
【例5-8】在Zgjk.dbf表中,查询姓名中第二个字为“家”的职工的信息。【例5-8】在Zgjk.dbf表中,查询姓名中第二个字为“家”的职工的信息。 在命令窗口中键入: SELECT * FROM Zgjk WHERE 姓名 LIKE "_家%" 【例5-9】在Zgjk.dbf表中,查询基本工资在1000元到1200之间的职工的信息。 在命令窗口中键入: SELECT * FROM Zgjk WHERE 基本工资 BETWEEN; 1000 AND 1200 该命令等价于: SELECT * FROM Zgjk WHERE 基本工资>=1000 AND ; 基本工资<=1200
3.对查询结果进行排序 在SELECT-SQL命令中,使用ORDER BY子句,可以使查询结果按指定要求排序。 命令格式:SELECT <列名表> FROM <表名> [WHERE <条件>]; ORDER BY <排序依据> [ASC|DESC] 说明: 排序依据:备注型数据和通用型数据不能作为排序依据。排序依据可以是字段名、由AS子句命名的列标题(在ORDER BY子句中,不能直接使用表达式和函数)和列序号(即该列在查询结果中的位置1,2,3…)。 排序方式:ASC表示查询结果按照排序依据项的值升序排列,DESC表示查询结果按照排序依据项的值降序排列。默认排序方式为ASC。 排序规则:数值按大小顺序,字母按“ a ” < “ A ” < “ b ” < “ B ” …的顺序,汉字按内码值顺序,日期按前后顺序,逻辑型数据“假”在前“真”在后。
如果有多个排序依据,它们之间用逗号分隔。在排序时,先按第一个排序关键字排序,若第一个排序关键字的值相同,再按第二个排序关键字排序,依次类推。如果有多个排序依据,它们之间用逗号分隔。在排序时,先按第一个排序关键字排序,若第一个排序关键字的值相同,再按第二个排序关键字排序,依次类推。 (1)单关键字排序 【例5-10】在Zgjk.dbf表中,查询所有职工的职工号、姓名和年龄,并按年龄由小到大顺序排列。 在命令窗口中键入: SELECT 职工号,姓名,YEAR(DATE())-YEAR(出生日期) AS 年龄; FROM Zgjk ORDER BY 年龄 (2)多关键字排序 【例5-11】在Zgjk.dbf表中,查询职工的信息,并按部门升序排列,部门相同时按基本工资降序排列。 在命令窗口中键入: SELECT * FROM Zgjk ORDER BY 部门,基本工资 DESC
4.对查询结果进行分组 在SELECT-SQL命令中,使用GROUP BY子句,可以使查询结果按指定依据和条件分组。所谓的分组就是按<分组依据>表达式的值对查询结果进行分类汇总。 格式:SELECT <列名表> FROM <表名> [WHERE <条件>]; GROUP BY <分组依据> [HAVING <条件>] 说明: 分组依据:备注型数据和通用型数据不能作为分组依据;分组依据可以是字段名和列序号(在GROUP BY子句中,不能直接使用表达式和函数)。 分组条件:在GROUP子句中使用HAVING子句,对分组的结果进行筛选。注意WHERE子句和HAVING子句的区别:WHERE子句指定哪些记录能参加分组,HAVING子句指定分组后哪些记录能作为查询的最终结果输出。
【例5-12】在Zgjk.dbf表中,查询各部门职工的人数。【例5-12】在Zgjk.dbf表中,查询各部门职工的人数。 在命令窗口中键入: SELECT 部门,COUNT(*) AS 职工数 FROM Zgjk ; GROUP BY 部门 【例5-13】在Zgjk.dbf表中,统计各部门基本工资的总额,输出基本工资总额大等于2500的部门名称和基本工资总额。 在命令窗口中键入: SELECT 部门,SUM(基本工资) AS 基本工资总额 FROM Zgjk; GROUP BY 部门 HAVING 基本工资总额>=2500 【例5-14】在Zgjk.dbf表中,统计各部门已婚职工的基本工资的总额,并输出各部门名称和基本工资总额。 在命令窗口中键入: SELECT 部门,SUM(基本工资) AS 已婚职工基本工资总额 FROM; Zgjk WHERE 婚否 GROUP BY 部门
5.指定查询结果输出的目标 在SELECT-SQL命令中,使用TO子句,可以将查询结果输出到指定目标:主窗口、ASCII文件或打印机,VFP默认TO 浏览窗口。 (1)将查询结果输出到文本文件 【例5-15】在Zgjk.dbf表中,将基本工资最高的前2个职工的信息存储到文本文件TOP2GZ.txt中。 在命令窗口中键入: SELECT TOP 2 * FROM Zgjk TO FILE TOP2GZ ; ORDER BY 基本工资 DESC 若要显示文本文件TOP2GZ.txt的内容,可在命令窗口中键入: Type TOP2GZ.txt&&用TYPE命令显示无结构的文本文件。
6.指定查询结果保存的方向 在SELECT-SQL命令中,使用INTO子句,可以指定查询结果保存的方向。 (1)将查询结果保存到独立的表 【例5-16】在Zgjk.dbf表中,将男职工的信息存储到表文件MEN.dbf中。 在命令窗口中键入: SELECT * FROM Zgjk WHERE 性别="男" INTO TABLE MEN USE MEN&&打开表文件 BROWSE&&浏览显示表记录
(2)将查询结果保存到临时表 【例5-17】在Zgjk.dbf表中,将男职工的信息存储到临时表MENtmp中。 在命令窗口中键入: SELECT * FROM Zgjk WHERE 性别="男" ; INTO CURSOR MENtmp BROWSE&&显示内在中的临时表 注意:虽然用户可以像表文件一样使用临时表,但临时表不是文件,临时表生成在内存中。程序中常用临时表存储中间数据,当关闭程序文件时自动删除临时表。
(3)将查询结果保存到数组中 【例5-18】在Zgjk.dbf表中,将所有职工的信息存储到数组ARRtmp中。 在命令窗口中键入: SELECT * FROM Zgjk INTO ARRAY ARRtmp 命令执行后,第1条记录的各数据项将分别写入数组元素ARRtmp(1,1)~ARRtmp(1,8),通用型字段没有写入数组元素,第9条记录的数据项将分别写入数组元素ARRtmp(9,1)~ ARRtmp(9,8)。 若要查看数组元素的内容,可在命令窗口中键入: DISPLAY MEMORY LIKE ARRtmp
§5.2.2 多表查询 多表查询就是将两个或多个表的记录通过公共字段联接起来查询。联接运算是关系数据库中重要的操作。 VFP提供了4种类型的联接:内部联接、左联接、右联接和完全联接。其中内部联接是最常用的联接方式。 为了说明VFP的4种联接类型,将表Zgjk和Xs另存为表Zgjk2和Xs2,并对表记录做一些增减,如图5-19所示。 图5-19 表Zgjk2和Xs2窗口
1.两表间的内部联接(INNER JOIN)查询 内部联接是从相关的两个表中选取满足联接条件的记录,联接成新的记录作为查询结果输出。实现两表之间内联的方法有以下两种: (1)使用INNER JOIN和ON子句 SELECT <列名表> FROM <表名1>; INNER JOIN <表名2> ON <表名1>.<关联字段>=<表名2>.<关联字段> (2)使用WHERE子句 SELECT <列名表> FROM <表名1>,<表名2>; WHERE <表名1>.<关联字段>=<表名2>.<关联字段>
【例5-19】根据表Zgjk2和Xs2,查询有职工号的职工的职工号、姓名、商品编号和销售数量。【例5-19】根据表Zgjk2和Xs2,查询有职工号的职工的职工号、姓名、商品编号和销售数量。 在命令窗口中键入: SELECT Zgjk2.职工号,姓名,商品编号,销售数量; FROM Zgjk2 INNER JOIN Xs2 ON Zgjk2.职工号=Xs2.职工号 或者 SELECT Zgjk2.职工号,姓名,商品编号,销售数量; FROM Zgjk2, Xs2 WHERE Zgjk2.职工号=Xs2.职工号
两个表满足内部联接条件“Zgjk2.职工号=Xs2.职工号”的查询结果如图5-20所示。两个表满足内部联接条件“Zgjk2.职工号=Xs2.职工号”的查询结果如图5-20所示。 图5-20 内部联接查询结果
2.两表间的左联接(LEFT JOIN)查询 从表1中选取所有记录,按联接条件与表2中相关的记录联接成新的记录作为查询结果输出,若表2中不存在相关联的记录,则查询结果输出中相应字段的值为.NULL.。实现两表之间左联接的命令格式为: SELECT <列名表> FROM <表名1>; LEFT JOIN <表名2> ON <表名1>.<关联字段>=<表名2>.<关联字段> 【例5-20】根据表Zgjk2和Xs2,查询所有职工的职工号、姓名、商品编号和销售数量,如果Zgjk2表中的职工没有相应销售记录,也要显示该职工的信息。 在命令窗口中键入: SELECT Zgjk2.职工号,姓名,商品编号,销售数量; FROM Zgjk2 LEFT JOIN Xs2 ON Zgjk2.职工号=Xs2.职工号
两表左联查询结果如图5-21所示。 图5-21 左联接查询结果
3.两表间的右联接(RIGHT JOIN)查询 从表2中选取所有记录,按联接条件与表1中相关的记录联接成新的记录作为查询结果输出,若表1中不存在相关联的记录,则查询结果输出中相应字段的值为.NULL.。实现两表之间右联接的命令格式为: SELECT <列名表> FROM <表名1> RIGHT JOIN <表名2> ; ON <表名1>.<关联字段>=<表名2>.<关联字段> 【例5-21】根据表Zgjk2和Xs2,查询所有职工的职工号、姓名、商品编号和销售数量,如果某个职工在Xs2表中没有相应的记录,也要显示该职工的信息。 在命令窗口中键入: SELECT Zgjk2.职工号,姓名,商品编号,销售数量; FROM Zgjk2 RIGHT JOIN Xs2 ON Zgjk2.职工号=Xs2.职工号
两表右联查询结果如图5-22所示。 图5-22 右联接查询结果
4.两表间的完全联接(FULL JOIN)查询 从相关的两表中选取所有记录,按联接条件联接成新的记录作为查询结果输出,若表1或表2中不存在相关联的记录,则查询结果输出中相应字段的值为.NULL.。实现两表之间完全联接的命令格式: SELECT <列名表> FROM <表名1> FULL JOIN <表名2>; ON <表名1>.<关联字段>=<表名2>.<关联字段> 【例5-22】将表Zgjk2和Xs2完全联接,查询两表所涉及到的所有职工的职工号、姓名、商品编号和销售数量的信息。 在命令窗口中键入: SELECT Zgjk2.职工号,姓名,商品编号,销售数量; FROM Zgjk2 FULL JOIN Xs2 ON Zgjk2.职工号=Xs2.职工号
两表全联查询结果如图5-23所示。 图5-23 完全联接查询结果 注意:全联扣除空值的记录即内联。
5.多表间的联接查询 为了介绍多表间的联接查询,增加Sp2表,如图5-24所示。 【例5-23】根据表Zgjk2、Xs2和Sp2,查询有职工号的职工的职工号、姓名、商品编号、商品名称、品牌、规格型号和销售数量,并按职工号从小到大排序输出。 图5-24Sp2表
在命令窗口中键入: SELECT Zgjk2.职工号,姓名,Xs2.商品编号,商品名称,品牌,规格型号,销售数量; FROM Zgjk2 INNER JOIN Xs2; INNER JOIN Sp2 ; ON Xs2.商品编号 = Sp2.商品编号 ; ON Zgjk2.职工号 = Xs2.职工号 ; ORDER BY Zgjk2.职工号 或者 SELECT Zgjk2.职工号,姓名,Xs2.商品编号,商品名称,品牌,规格型号,销售数量FROM Zgjk2, Xs2, Sp2; WHERE Zgjk2.职工号=Xs2.职工号 AND Xs2.商品编号=Sp2.商品编号; ORDER BY Zgjk2.职工号
§5.2.3 嵌套查询 嵌套子查询是指在SELECT-SQL命令中包含了另一个SELECT-SQL命令。嵌套子查询SELECT-SQL命令的形式如下: SELECT <表1的列名表> FROM <表名1>; WHERE <表1的关联字段> IN; (SELECT <表2的关联字段> FROM <表名2> WHERE <表2的查询条件>) 说明:命令中“IN”是一个关系运算符,表示表1中关联字段的值必须与从表2查询出的关联字段中的一个的值相匹配。 命令执行过程:首先执行子查询,然后执行外查询。
本例既可以使用嵌套子查询,也可以不使用嵌套子查询,而使用内联查询。 本例既可以使用嵌套子查询,也可以不使用嵌套子查询,而使用内联查询。 (1)使用嵌套子查询 在命令窗口中键入: SELECT 职工号,姓名 FROM Zgjk WHERE 职工号 IN ; ( SELECT 职工号 FROM Xs WHERE 销售数量>=5 ) 查询结果如图5-26示。 【例5-24】根据表Zgjk和Xs,查询销售数量在5以上(含5)的职工的职工号与姓名(要求不重复显示)。 图5-26 例5-24查询的结果
(2)不使用嵌套子查询 在命令窗口中键入: SELECT DISTINCT Zgjk2.职工号,姓名 FROM Zgjk; INNER JOIN Xs ON Zgjk.职工号=Xs.职工号; WHERE 销售数量>=5 或者 SELECT DISTINCT Zgjk2.职工号,姓名 FROM Zgjk,Xs; WHERE Zgjk.职工号=Xs.职工号 AND 销售数量>=5 不使用嵌套子查询和使用嵌套子查询的结果相同。
§5.2.4 自联查询 自联查询的含意:在SELECT-SQL命令将一个关系与其自身进行联接而进行的查询。为了区分内外层查询,在FROM子句中为内外层关系指定不同的别名。 自联查询的命令格式如下: SELECT <别名1.列名表> FROM <表名> <别名1> WHERE <自联字段>=; (SELECT <自联字段> FROM <表名> <别名2>; WHERE <别名1.关联字段=别名2.关联字段>) 【例5-25】查询每个职工销售数量最高的商品编号的信息。 在命令窗口中键入: SELECT out.职工号,out.商品编号,out.销售数量; FROM Xs out WHERE 销售数量=; (SELECT MAX(销售数量) FROM Xs inner1; WHERE out.职工号=inner1.职工号)
自联查询结果如图5-27所示。 图5-27 例5-25查询的结果
§5.2.5 集合的并运算 SQL支持集合的并运算,即使用并算符(UNION)将两个SELECT-SQL语句的查询结果合并成一个查询结果。 命令格式: SELECT <列名表1> FROM <表名1> WHERE <条件1>…; UNION; SELECT <列名表2> FROM <表名2> WHERE <条件2>… 功能:将两个SELECT-SQL语句的查询结果合并成一个查询结果输出。 说明:在两个SELECT-SQL语句中,查询结果<列名表>中的字段个数、字段的名、型和宽都要相同。
【例5-26】查询在家电和文具部门工作的职工的信息。【例5-26】查询在家电和文具部门工作的职工的信息。 在命令窗口中键入: SELECT * FROM Zgjk WHERE 部门="家电"; UNION; SELECT * FROM Zgjk WHERE 部门="文具" 查询结果如图5-28所示。 图5-28 例5-26查询的结果