SQL 的数据操作包括 SELECT(查询)、INSERT(插入)、DELETE(删除)和 UPDATE(修改)四条语句。
SELECT 基本结构
数据库查询是数据库的核心操作,语法格式如下:
SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>]... FROM <表名或视图名>[,<表名或视图名>] [WHERE <条件表达式>] [GROUP BY <列名> [HAVING<条件表达式>]] [ORDER BY <列名>[ASC|DESC]...]
SQL 查询中的子句顺序为SELECT、FROM、WHERE、GROUP BY、HAVING 和 ORDER BY。其中,SELECT、FROM 是必须的,HAVING 条件子句只能与 GROUP BY 搭配起来使用。
(1)SELECT 子句对应的是关系代数中的投影运算,用来列出查询结果中的属性。其输出可以是列名、表达式、函数集(AVG、COUNT、MAX、MIN、SUM),DISTINCT 选项可以保证查询的结果集不存在重复元组。
(2)FROM 子句对应的是关系代数中的笛卡尔积,它列出的表达式求值过程中需扫描的关系,即在 FROM 子句中出现多个基本表或视图时,系统首先执行笛卡尔积操作。
(3)WHERE 子句对应的是关系代数中的选择谓词。WHERE 子句的条件表达式可以使用的运算符如下:
简单查询
SQL 最简单的查询是找出关系中满足特定条件的元组,这些查询与关系代数中的选择操作类似,通常只需要使用三个关键字 SELECT、FROM 和 WHERE。
示例10. 查询所有员工信息;查询员工号为1088的员工的姓名和参加工作时间。
SELECT * FROM 员工; SELECT 姓名,参加工作时间 FROM 员工 WHERE 员工号 = 1088;
连接查询
如果查询涉及两个以上的表,则称为连接查询。
示例11. 关系模式:员工(员工号,姓名,性别,参加工作时间,部门号);部门(部门号,名称,电话,负责人);
# 查询部门名为“企业信息部”,且在2010年1月1日后入职的员工工号、姓名和性别 SELECT 员工号,姓名,性别 FROM 员工,部门 WHERE 员工.部门号 = 部门.部门号 AND 部门.名称 = '企业信息部' AND 参加工作时间 > '2010-01-01';
连接查询相同字段需要带上表名点前缀,字符类型,日期类型的数据需要使用单引号。
子查询
子查询也称嵌套查询。嵌套查询是指一个 SELECT-FROM-WHERE 查询块可以嵌入另一个查询块之中。在 SQL 中允许多重嵌套。
示例12. 查询部门名为“企业信息部和行政部”,所有员工的工号、姓名和性别。
SELECT 员工号,姓名,性别 FROM 员工 WHERE 部门号 IN (SELECT 部门号 FROM 部门 WHERE 名称 IN ('企业信息部','行政部'));
聚集函数和更名操作
聚集函数是一个值的集合输入,返回单个值的函数。
SQL提供了5个预定义集函数:平均值AVG、最小值MIN、最大值MAX、求和SUM以及计数COUNT;
使用ANY和ALL谓词必须同时使用比较运算符,其含义及等价的转换关系如下:
使用聚合函数实现子查询比直接用 ALL 或 ANY 查询效率要高。
更名操作:SQL提供可为关系和属性重新命名的机制,可以使用 AS 来操作。as 子句可以出现在SELECT 子句中,也可出现在FROM子句中
示例13. 查询课程C1的最高分和最低分以及高低分之间的差距。
SELECT MAX(Grade) AS MAX_Grade ,MIN(Grade) AS MIN_Grade ,MAX(Grade)-MIN(Grade) AS GAP FROM SC AS X WHERE Cno='C1';
示例14. 查询其他系比计算机系CS所有学生年龄都要小的学生姓名及年龄。
## 方法一 SELECT Sname,Sage FROM S WHERE Sage < ALL(SELECT Sage FROM S WHERE SD='CS') AND SD <> 'CS'; ## 方法二 SELECT Sname,Sage FROM S WHERE Sage < (SELECT MIN(Sage) FROM S WHERE SD = 'CS') AND SD <> 'CS';
分组查询
在 WHERE 子句后面加上 GROUP BY 子句可以对元组进行分组,关键字 GROUP BY 后面跟着一个分组属性列表。如元组在分组后需要过滤,可以在后面加 HAVING 子句即可。
当元组含有空值时,应该记住以下两点:
(1)空值在任何聚集操作中都会被忽视。它对求和、求平均值和计数都没有影响。它也不能是某列的最大值或最小值。例如,COUNT(*)
是某个关系中所有元组数目之和,但 COUNT(A) 却是A属性非空的元组个数之和。
(2)NULL 值又可以在分组属性中看作是一个一般的值。例如,SELECT A,AVG(B) FORM R 中,当A的属性值为空时,就会统计A=NULL的所有元组中B的均值。
示例15. 供应商数据库中的S、P、J、SPJ关系,查询某工程至少用了三家供应商(包含三家)供应的零件的平均数量,并按工程号的降序排列
SELECT Jno,AVG(QTY) FROM SPJ GROUP BY Jno HAVING COUNT(DISTINCT(Sno)) > 2 ORDER BY Jno DESC
字符串操作
谓词 LIKE 可以用来进行字符串匹配,通常也称模糊查询,语法格式如下:
[NOT] LIKE '<匹配串>'[ESCAPE'<换码字符>']
# (1) SELECT Sname FROM S WHERE Addr LIKE '%科技路%'; # (2) SELECT Sname,Sage,SD FROM S WHERE Sname LIKE '_ _晓军';
为了使模式中包含特殊模式字符(即%和_),在SQL中允许使用 ESCAPE 关键词来定义转义符。转义字符紧靠着特殊字符,并放在它的前面,表示该特殊字符被当成普通字符。例如,在LIKE比较中使用ESCAPE关键词来定义转义符,例如使用反斜杠\
作转义符。
LIKE 'ab\%cd%'ESCAPE '\',匹配所有以阿宝%cd开头的字符串。 LIKE 'ab\\cd%'ESCAPE '\',匹配所有以ab\cd开头的字符串。
集合操作
在关系代数中可以用集合的并、交和差来组合关系。SQL也提供了对应的操作,但是查询的结果必须具有相同的属性和类型列表。保留字UNION、INTERSECT和EXCEPT分别对应 ∪ 、 ∩ \cup、\cap∪、∩和—。保留字用于两个查询时,应该将每个查询分别用括号括起来。
UNION 运算
示例17. 假设查询所有客户的集合的语句1为:SELECT Customer-no FROM depositor;查询有贷款客户的集合的语句2为:SELECT Customer-no FROM borrower。查询在银行有账户、有贷款或两者都有的所有客户身份证号。
# 1和2 取并集,使用 UNION 运算会自动去除重复 SELECT Customer-no FROM depositor UNION SELECT Customer-no FROM borrower; # 1和2 取并集,使用 UNION ALL 运算会保留重复 SELECT Customer-no FROM depositor UNION ALL SELECT Customer-no FROM borrower;
INTERSECT 运算
示例18. 学生关系模式为Students (Name, Sno, SEX, SD, Type, Address),教师关系模式为Teachers (Name, Eno, SEX, Salary, Address),查询既是女研究生,又是教师且工资大于等于2600元的名字和地址。
(SELECT Name, Address FROM Students WHERE SEX='女' AND rype='研究生') INTERSECT (SELECT Name, Address FROM Teachers WHERE Salary>=2600);
EXCEPT 运算
示例19.查询不是教师的学生姓名。
(SELECT Name, Address FROM Students) ЕХСЕРТ (SELECT Name, Address FROM Teachers);
视图查询和更新
查询视图表时,系统先从数据字典中取出该视图的定义,然后将定义中的查询语句和对该视图的查询语句结合起来,形成一个修正的查询语句。
# 创建视图 CREATE VIEW V_ITEmp AS SELECT 员工号,姓名,性别 FROM 员工,部门 WHERE 员工.部门号 = 部门.部门号 AND 部门.名称 = 'IT部'; # 查询IT部性别为‘女’员工的姓名工号 SELECT 员工号,姓名 FROm V_ITEmp WHERE 性别 = '女';
视图更新
SQL 对视图更新必须遵循以下规则:
(1) 从多个基本表通过连结操作导出的视图不允许更新。
(2) 对使用了分组、聚集函数操作的视图则不允许进行更新操作。
(3) 如果视图是从单个基本表通过投影、选取操作导出的则允许进行更新操作,且语法同基本表。
WITH 子句
With 子句是在SQL99中引入的,目前只有部分数据库支持这一子句。如果我们将一个复杂查询分解成一些小视图,然后将它们组合起来,就像将一个程序按其任务分解成一些过程一样,使得复杂查询的编写和理解都会简单得多。
示例20. 假定教师关系模式为Teachers(TName,Eno,Tdept,SEX,Salary,Address),利用With子句查询工资最高的教师姓名。此时,如果具有同样工资最高的教师有多个,他们都会被选择。
with max-Salary (value) AS (SELECT max (Salary) FROM Teachers) SELECT Tname FROM Teachers, max-Salary WHERE Teachers.Salary = max-Salary.value;
其他语句
插入语句语法如下:
INSERT INTO 表名(列名[,...n]) VALUES (常量[,...n]); INSERT INTO 表名(列名[,...n]) SELECT 查询语句;
删除语句语法如下:
DELETE FROM 表名 WHERE 条件表达式;
更新语句语法如下:
UPDATE 表名 SET 列名=值表达式(,列名=值表达式) [WHERE 条件表达式];
总结
SQL语言,作为数据库操作的核心语言,提供了强大的数据操作能力。在SQL中,数据操作主要涉及数据的插入、更新、删除和查询,这些操作共同构成了数据库日常管理和使用的基础。掌握这些数据操作技巧对于任何希望建立有效数据管理系统的信息技术人员来说是至关重要的。随着数据驱动决策在现代业务中的地位日益提升,精通SQL数据操作成为了获取洞察力、做出快速决策、并最终推动业务增长的关键。无论是分析师、数据库管理员还是应用程序开发者,都应不断深化对SQL数据操作的理解和实践,从而确保他们能够有效地利用数据资源,为企业带来更大的价值。