《数据库系统概念》第三章
第三章 SQL
SQL(结构化查询语言)是使用最广泛的数据库查询语言。
尽管我们说 SQL 语言是种”查询语言“,但除了数据库查询,它还具有很多其他功能:定义数据结构、修改数据库数据、说明安全性约束条件等。
我们将介绍 SQL 的基本结构和概念,SQL 的各种实现可能在一些细节上有所不同,或只支持整个语言的一个子集。
3.1 SQL 查询语言概览
SQL语言有👇部分
数据定义语言 DDL
:SQL DDL 提供定义、删除、修改关系模式的命令。数据操纵语言 DML
:SQL DML 提供从数据库中查询信息,及插入、删除、修改元组的能力。完整性
:SQL DDL 包含定义完整性约束的命令。- 保存在数据库中的数据必须满足所定义的完整性约束。破坏完整性约束的更新时不允许的。
视图定义
:SQL DDL 包含定义视图的命令。事务控制
:SQL 包含定义事务的开始和结束的命令。嵌入式 SQL 和动态 SQL
:嵌入式和动态 SQL 定义 SQL 语句如何嵌入到编程语言,如 C、C++、Java中。授权
:SQL DDL 包含定义对关系和视图的访问权限的命令。
本章我们给出对 SQL 的基本 DML 和 DDL 特征的概述。
在此描述的特征自 SQL-92 以来就一直是 SQL 标准的部分。
3.2 SQL 数据定义
数据库中的关系集合必须由数据定义语言(DDL)指定给系统。
DDL 不仅能定义一组关系,还能定义每个关系的信息,包括:
- 每个关系的模式
- 每个属性的取值类型
- 完整性约束
- 每个关系维护的索引集合
- 每个关系的安全性和权限信息
- 每个关系在磁盘上的物理存储结构
本章只讨论基本模式定义和基本类型,SQL DDL 的其他特征将在第4、5章讨论。
3.2.1 基本类型
SQL 标准支持多种固定类型:
char(n)
:固定长度的字符串,用户指定长度 。也可使用全称character
。varchar(n)
:可变长度的字符串,用户指定最大长度 。等价于全称character varying
。int
:整数类型(和机器相关的整数的有限子集)。等价于全称integer
。smallint
:小整数类型(和机器相关的整数类型的子集)。numeric(p, d)
:定点数,精度由用户指定 —— 有 位数字(加上一个符号位)其中 位数字在小数点右边。real
,double precision
:浮点数与双精度浮点数,精度与机器有关。float(n)
:精度至少为 位的浮点数。
每种类型都包含一个特殊值 —— 空值
:表示一个缺失的值,该值可能不存在或未知。
SQL 提供 nvarchar
类型存放使用 Unicode 表示的多语言数据。但很多数据库允许在 varchar 类型中存放 Unicode(用UTF_8表示)
- char 数据类型存放固定长度的字符串。
🌰 属性 A 的类型为 char(10),若我们为 A 属性存入字符串”Avi“,则该字符串后会追加7个空格使其达到10个字符的长度;反之,若属性 B 的类型为varchar(10),存入”Avi“,则不会增加空格。
比较两个 char 类型的值时,若二者长度不同,则在比较之前会自动在短值后增加额外空格使二者长度一致。
比较 char 类型和 varchar 类型时,是否会在 varchar 类型后增加空格使二者长度一致,取决于数据库系统。故建议始终使用 varchar 类型而不是 char 类型以避免此问题。
3.2.2 基本模式定义
-
定义 SQL 关系:
create table
create table r ( A1 D1, A2 D2, ..., An Dn, <完整性约束1>, ..., <完整性约束k>);
-
是关系名; 是关系 模式中的一个属性名, 是属性 的域;
也就是说 指定了属性 的类型以及可选的约束,用于限制所允许的 取值的集合。
-
完整性约束:
-
primary key
声明属性 构成关系的主码。主码属性必须非空且唯一。
-
foreign key references
声明关系中任意元组在属性 上的取值必须对应于关系 中某些元组在主码属性上的取值。
-
not null
一个属性上的 not null 约束表明该属性上不允许空值。
-
create table instructor (ID varchar(5), name varchar(20) not null, dept_name varchar(20), salary numeric(8,2), primary key(ID), foreign key(dept_name) reference department);
-
-
删除 SQL 关系:
drop table
drop table r;
-
修改 SQL关系:
alter table
alter table r add A D; -- 为已有关系 r 增加属性,A 是待添加的属性名,D 是待添加属性的域
alter table r drop A; -- 删除已有关系 r 中的属性 A
- 将数据加载到关系中:
insert
insert into instructor
values(10211, 'Smith', 'Biology', 66000);
- 从关系中删除所有元组:命令
delete
delete from r; -- 删除关系 r 中的所有元组
delete from r where P; -- 删除关系 r 中满足 P 条件的元组
命令以分号结束,但在很多 SQL 实现中分号可选。
3.3 SQL 查询的基本结构
SQL 查询的基本结构由子句 select、from、where 组成。
from
子句列出的关系是查询的输入,在这些关系上进行 where
、select
子句中指定的运算,然后产生一个关系作为结果。
3.3.1 单关系查询
“找出所有教师所在的系名”:select dept_name from instructor;
-
SQL允许在关系以及SQL表达式结果中出现重复,若要删除重复,可在 select 后加入关键词
distinct
。- 默认保留重复元组,也可使用关键词
all
显式指明不去除重复。
- 默认保留重复元组,也可使用关键词
-
select 子句可包含 算术表达式(含 +、-、*、/ 运算符),运算对象可为常数或元组的属性。
select ID, name, dept_name, salary*1.1 from instructor;
-
通过where子句选择满足特定谓词的元组,where子句中可使用
逻辑连词
and、or、not。- 逻辑连词的运算对象可以是包含比较运算符(<、>、<=、>=、=、<>)的表达式。
-
还可使用 between 比较运算符说明一个值>=某个值,且<=某个值。同理,还有 not between 比较运算符。
找出所有在Computer Science系且工资在7000到10000美元的教师姓名:
select name from instructor where dept_name = 'Comp.Sci.' and salary between 7000 and 10000;SQL 允许我们使用比较运算符来比较字符串、算术表达式、特殊类型(如日期类型)
3.3.2 多关系查询
-
涉及多个关系的SQL查询中,各子句作用:
- select 子句:列出查询结果中所需要的属性
- from 子句:列出查询求值中需要访问的关系
- where 子句:列出作用在 from 子句中关系的属性上的谓词
select 子句中,若有多个属性名相同,需使用关系名作为前缀加以区分。
-
理解查询所代表的的运算:
- 为 from 子句中列出的关系产生笛卡尔积
- 在步骤1的结果上应用 where 子句中指定的谓词
- 对步骤2结果中的每个元组,输出 select 子句中指定的属性(或表达式的结果)
上述步骤的顺序有助于理解SQL查询的结果应该是怎样的,而不是此结果怎样被执行的。
SQL 的实际实现中不会执行这种形式的查询,它尽可能只产生满足 where 子句谓词的笛卡尔积元素,以此优化执行。
-
星号“*” 可在 select 子句中表示“所有的属性”。
找出所有教师姓名,及他们所在系的名称和系所在建筑的名称:
select name, instructor.dept_name, building
from instructor, department
where instructor.dept_name = department.dept_name;
3.3.3 自然连接
-
自然连接
:natural join 作用于两个关系,并产生一个关系作为结果。只考虑 在两个关系模式中共同属性上取值相同的元组对。⚠️ 两个关系中可能存在多个共同属性,此时自然连接的结果为共同属性取值相同的元组对。
对大学中所有讲授课程的教师,找出他们的姓名及讲述的的所有课程标识:
select name, course_id from instructor, teachers where instructor.ID = teachers.ID
select name, course_id from instructor natural join teachers
若instructor表与teachers表只有ID这个共同属性,则上述二种写法等价,若还有其他共同属性,则两种写法不等价。 -
from 子句中,可用自然连接将多个关系结合在一起作为一个新的关系。
select A1, A2, ..., An from r1 natural join r2 natural join r3, r4 where P;
-
SQL 也提供了一种自然连接的构造形式,允许用户指定需要哪些列相等——
join···using 运算
,需给定一个共同属性名列表。select name, course_id from instructor join teachers using (ID)
3.4 附加的基本运算
3.4.1 更名运算
-
之前查询结果中的属性名为 from 子句中关系的属性名。可通过 as 子句重命名结果关系中的属性。
- as 子句可出现在 select 子句中,重命名属性
- as 子句可出现在 from 子句中,重命名关系
-
当需要比较同一关系中元组的情况时,重名名关系是必须的。
找出满足下面条件的所有教师的姓名,他们的工资至少比 Biology系某一个教师的工资要高:
select distinct T.name
from instructor as T, instructor as S
where T.salary > S.salary and S.dept_name = 'Biology'; -
相关名称/表别称/相关变量/元祖变量
:被用于重命名关系的标识符。 👆的 T 和 S
3.4.2 字符串运算
-
字符串用 单引号标识,用两个单引号标识字符串中原本的单引号字符。字符串 'it''s right' 的含义是 it's right
-
SQL 标准中 字符串匹配大小写敏感,表达式“ 'comp.sci.' = 'Comp.Sci.' ”结果为假。但一些数据库如 MySQL、SQL Server中,不区分大小写。但这种默认方式可在数据库级或特定属性级被修改。
-
SQL 中由很多操作字符串的函数:
upper(s)
将字符串 s 转换为大写;lower(s)
将字符串 s 转换为小写trim(s)
去除字符串 s 后面的空格substring(s,first,last)
选取s的子串
-
使用 like 操作符实现字符串的模式匹配,使用 escape 关键词定义转义字符;使用 not like 比较运算符搜寻不匹配项。
- 百分号(%):匹配任意子串
- 下划线(_):匹配任意一个字符
like 'ab%cd%' escape '\' 匹配所有以“ab%cd”开头的字符串。
找出所有建筑名称中包含子串 ’Watson‘ 的所有系名:
select dept_name
from department
where building like '%Watson%';
3.4.3 排列元组的显示次序
order by 子句:让查询结果的元组按排列顺序显示。
- 使用 desc 表示降序,asc 表示升序,默认使用升序。
- 排序可在多个属性上进行。
按工资的降序列出整个instructor关系,若教师工资相同则按姓名升序排列:
select *
from instructor
order by salary desc, name asc;
3.4.4 where 子句谓词
SQL 允许使用记号 (v1, v2, ..., vn)表示一个分量值分别为 v1, v2, ..., vn 的n维元组。在元组上可使用比较运算符,将按 字典顺序 进行比较运算。
(a1, a2) <= (b1, b2) 在 a1<=b1 且 a2<=b2 时为真
查找Biology系讲授了课程的所有教师的姓名和他们所讲授的课程:
select name, course_id from instructor, teacher where instructor.ID = teacher.ID and dept_name = 'Biology';
select name, course_id from instructor, teacher where (instructor.ID, dept_name) = (teacher.ID, 'Biology') ;
二者写法等价。
3.5 集合运算
SQL 作用在关系上的 union、intersect、expect 运算对应于数学集合论中的
3.5.1 并运算
查找在2009年秋季开课,或在2010年春季开课,或在两个学期都开课的所有课程:
( select course_id from section where semester = 'Fall' and year = 2009 )
union
( select course_id from section where semester = 'Spring' and year = 2010 )
- union 运算自动去除重复。
- 若想保留重复,必须使用 union all 替代 union。结果中重复元组数 = 关系c1 和 c2 中出现的重复元组数之和。
3.5.2 交运算
将👆的 union 改为 intersect,则可查找在2009年秋季和2010年春季同时开课的所有课程。
- intersect 运算自动去除重复。
- 若想保留重复,必须使用 intersect all 替代 intersect。结果中重复元组数 = 关系c1 和 c2 中出现的重复次数最少的那个。
3.5.3 差运算
将👆的 union 改为 expect,则可查找在2009年秋季开课,且不在2010年春季开课的所有课程。
- expect 运算自动去除重复。
- 若想保留重复,必须使用 expect all 替代 expect。结果中重复元组数 = c1中出现的重复元组数 - c2中出现的重复元组数(前提是此差为正)。
3.6 空值
空值会给关系运算带来特殊问题,包括算术运算、比较运算、集合运算。
- 使用 is null 或 is not null 可判断表达式结果是否为空值。
- 若 算术表达式 的任一输入为空 null,则该算术表达式(涉及诸如 +、-、*、/)结果为空 null。
- 涉及空值的任何 比较运算 的结果为 unknown。
- 这是除 true、false 外的第三个逻辑值。
- 可使用 is unknown 或 is not unknown 判断表达式结果是否为 unknown。
- where 子句中的
逻辑谓词
and、or、not 可对比较结果进行布尔运算,这些布尔运算的定义也被扩展到可处理 unknown 值。
- true and unknown 结果为 unknown,false and unknown 结果为 false
- true or unknown 结果为 true,false or unknown 结果为 unknown
- not unknown 结果为 unknown
- 当查询使用 select distinct 子句时,会去除重复元组——元组在所有属性上的取值都相等即视为重复元组,即使某些值为空。
- 这种对待空值的方式,与谓词中对待空值的方式不同,谓词中 “null=null” 会返回 unknown,而不是 true。
- 这也适用于 集合 的并、交、差运算。
3.7 聚集函数
-
聚集函数
:以值的一个集合(集或多重集)为输入、返回单个值的函数。 -
SQL中提供的聚集函数:
- 平均值:avg
- 最小值:min
- 最大值:max
- 总和:sum
- 计数:count
avg、sum 的输入必须为数字集合,其他可作用在非数字集合上,如字符串。
3.7.1 基本聚集
找出 2010年春季学期讲授一门课程的教师总数:
select count(distinct ID) as teachers_count
from teachers
where semester = 'Spring' and year = 2010 ;
- 若结果关系中的某属性由聚集产生,则数据库会给她一个任意的名字,我们可使用 as 子句给它重命名。
- 有时在计算聚集函数前需使用 distinct 去除重复值,有时不用 比如计算平均值时。
- count(*) 可计算一个关系中的元组个数,但使用 count(*) 时不能使用 distinct。
- 使用 max、min 时可使用 distinct,但结果不会有差别。
3.7.2 分组聚集
将聚集函数作用在一组元组集上。
- 通过 group by 子句中给出的一个/多个属性构造分组,属性上取值都相同的元组被分为一组。
- 不写 group by 子句时,可将整个结果视作一个分组。
- select 子句中只能有被聚集的属性和出现在 group by 子句中的属性。
- having 子句可设置分组的限定条件。
- having 子句中的谓词在形成分组后才能起作用。
- having 子句中只能有被聚集的属性和出现在 group by 子句中的属性。
- 包含聚集、group by、having 子句的查询的含义理解:
- 根据 from 子句计算出一个关系。可理解为 from 中列出的关系做笛卡尔积
- 将 where 子句中的谓词应用到 from 子句的结果关系上。
- 若出现 group by 子句,将满足 where 谓词的元组通过 group by 子句形成分组;若无 group by 子句,则将满足 where 谓词的元组视为一个分组。
- 若出现 having 子句,将它应用到每个分组上,不满足 having 子句谓词的分组将被舍弃。
- select 子句利用剩下的分组产生查询结果的元组(在每个分组上应用聚集函数来得到单个元组)。
对于在2009年讲授的每个课程段,若该课程段有至少2名学生选课,找出选修该课程段的学生的总学分的平均值:
select course_id, sec_id, semester, year, avg(tot_cred)
from takes natural join student
where year = 2009
group by course_id, sec_id, semester, year
having count(ID) >=2 ;
3.7.3 对空值和布尔值的聚集
- 除了 count(*) 外,所有的聚集函数都忽略输入集合中的空值。
- 空集 的 count 运算值为0,其余聚集运算返回一个空值。
3.8 嵌套子查询
子查询
:是嵌套在另一个查询的 where 子句中的 select-from-where 表达式。- 子查询常用于对集合的成员资格、集合的比较以及集合的计数进行检查。
3.8.1 集合成员资格
-
连接词 in 测试元组是否是集合中的成员,连接词 not in 测试元组是否不是集合中的成员。
-
集合由 select 子句产生的一组值构成(子查询)
找出在2009年秋季和2010年春季学期同时开课的所有课程:
select distinct course_id
from section
where semester = 'Fall' and year = 2009 and course_id in (select course_id
from section
where semester = 'Spring' and year = 2010 ) ;此查询也可由交运算完成。
-
集合也可由 枚举 构成
找出既不叫 “Mozart”又不叫“Einstein”的教师姓名:
select distinct name
from instructor
where name not in ('Mozart', 'Einstein') ;
-
-
👆的例子中都是在单属性关系中测试成员资格,也可测试任意关系的成员资格。
找出选修了ID为10101教师教授课程的学生总数:
select count(distinct ID)
from takes
where (course_id, sec_id, semester, year) in (select course_id, sec_id, semester, year
from teachers
where teachers.ID = 10101 ) ;
3.8.2 集合的比较
some关键词 | 含义 | all关键词 | 含义 |
---|---|---|---|
< some | 至少小于某一个 | < all | 小于所有 |
<= some | 至少小于等于某一个 | <= all | 小于等于所有 |
> some | 至少大于某一个 | > all | 大于所有 |
>= some | 至少大于等于某一个 | >= all | 大于等于所有 |
= some | 至少等于某一个 | = all | 等于所有 |
<> some | 至少不等于某一个 | <> all | 不等于所有 |
= some 等价于 in,<> some 不等价于 not in;<> all 等价于 not in,= all 不等价于 in。
找出满足下面条件的所有教师的姓名,他们的工资至少比 Biology 系某一个教师的工资要高:
select distinct T.name
from instructor as T, instructor as S
where T.salary > S.salary and S.dept_name = 'Biology';
等价于:
select name
from instructor
where salary > some (select salary
from instructor
where dept_name = 'Biology';
子查询产生 Biology 系所有教师的所有工资值集合。当元组的salary值至少比 Biology 系教师的所有工资值集合中某一成员高时,外层 select 的where 子句中 >some 的比较为真。
3.8.3 空关系测试
-
SQL 可测试一个子查询的结果中是否存在元组。
-
exists 结构测试子查询结果集中是否存在元组,子查询非空时返回 true。可用于两个条件同时发生的查询
找出在2009年秋季和2010年春季学期同时开课的所有课程,也可写为:
select distinct course_id
from section as S
where semester = 'Fall' and year = 2009 and exist (select *
from section as T
where semester = 'Spring' and year = 2010 and S.course_id = T.course_id) ; -
not exists 结构测试子查询结果集中是否不存在元组,子查询为空时返回 true。
-
“关系 A 包含关系 B”可写成“not exists( B except A)”。
找出选修了Biology系开设的所有课程的学生(也就是找到这样的学生,他们不存在Biology系开设的课程没有选修的):
select S.ID, S.name
from student as S
where not exists (( select course_id
from course
where dept_name = 'Biology')
except
(select T.course_id
from takes as T
where S.ID = T.ID) ;
第一个子查询找出Biology系开设的所有课程集合;第二个子查询找出S.ID选修的所有课程。外层 select 对每个学生测试其选修的所有课程集合是否包含Biology系开设的所有课程集合。
-
-
相关子查询
:使用了来自外层查询相关名称的子查询。
3.8.4 重复元组存在性测试
SQL 可测试一个子查询的结果是否存在重复元组。
-
unique 结构测试子查询结果中是否不存在重复元组。子查询没有重复元组时返回 true。
找出所有在2009年最多开设一次的课程:(意思是也有可能没开设)
select T.course_id
from course as T
where unique (select R.course_id
from section as R
where T.course_id = R.course_id and R.year = 2009) ;在不使用 unique 结构的情况下,等价于:
select T.course_id
from course as T
where 1>= (select count (R.course_id)
from section as R
where T.course_id = R.course_id and R.year = 2009) ; -
not unique 结构测试子查询结果中是否存在重复元组。子查询有重复元组时返回 true。
将👆例子中的 unique 改为 not unique 则表示找出所有在2009年最少开设两次的课程。
⚠️ unique谓词在空集上计算为 true。 此结构尚未被广泛实现🤦♀️。
3.8.5 from子句中的子查询
- SQL可在 from 子句中使用子查询表达式。
- 因为任何 select-from-where 表达式返回的结果都是关系,故可以被插入到另一个 select-from-where 中任何关系可出现的位置
- from 子句嵌套的子查询的结果属性可在外层查询中使用。
- from 子句嵌套的子查询不能使用来自 from 子句其他关系的相关变量。
- 可使用 as 子句给子查询的结果关系起个名字,并对属性进行重命名。
找出所在系中工资总额最大的系:(在此无法使用 having 子句实现查询)
select max(total_salary)
from (select dept_name, sum(salary)
from instructor
group by dept_name) as dept_total(dept_name, tot_salary)
⚠️ 并非全部 SQL 实现都支持在 from 子句中嵌套子查询。
某些 SQL 实现要求对每个子查询结果关系都给一个名字,即使该名字从不被引用。
Oracle允许对子查询结果关系命名(省略掉 as 关键字)但不允许对关系中的属性重命名。
3.8.6 with子句
with 子句提供定义临时关系的方法,此定义只对包含 with 子句的查询有效。
- 使用 with 子句能使查询在逻辑上更加清晰
- 它还允许在一个查询内的多个地方使用视图定义。
查找所有工资总额大于所有系平均工资总额的系:
with dept_total(dept_name, value) as
(selelct dept_name, sum(salary)
from instructor group by dept_name)
dept_total_avg(value) as
(select avg(value) from dept_total)
select dept_name from dept_total, dept_total_avg
where dept_total.value >= dept_total_avg.value ;
⚠️ 并非全部 SQL 实现都支持 with 子句。
3.8.7 标量子查询
- SQL 允许子查询出现在返回单个值的表达式能够出现的任何地方,只要该子查询只返回包含单个属性的但个元组。——这样的子查询称为
标量子查询
:只返回含单个属性的单个元组。- 技术上,标量子查询的结果类型仍是关系,尽管其中只包含单个元组。
- 在表达式中使用标量子查询时,它出现的位置是单个值出现的地方,则SQL就从该关系中包含单属性的单元组中取出相应的值并返回。
- 在编译时并非总能判断一个子查询返回的结果是否含多个元组;若在子查询被执行后其结果中有多个元组,则会产生
运行时错误
。
- 标量子查询可出现在 select、where、having 子句中。
列出所有的系以及它们拥有的教师数:此例也说明了标量子查询中对相关变量(外层查询的 from 子句中关系的属性)的使用
select dept_name,
(selelct count(*) from instructor
where department.dept_name = instructor.dept_name)
as num_instructors
from department ;
3.9 数据库的修改
3.9.1 删除
- 删除操作只能删除整个元组,无法只删除元组某些属性上的值。
- delete 命令只能作用于一个关系。
- 一次只能从一个关系中删除元组,但通过在 where 子句中嵌套 select-from-where 就可引用任意数目的关系。
delete from r where P ; -- 先从 r 中找出所有使 P 为真的元组,然后将其从 r 中删除。若省略 where 子句,则删除 r 中所有元组
删除工资低于大学平均工资的教师记录:
delete from instructor
where salary < (select avg(salary) from instructor) ;
3.9.2 插入
-
待插入元组的属性值必须在相应属性的域中,待插入元组的分量数也必须正确。
-
待插入的元组可能只给出了模式中部分属性的值,则剩余属性会被赋为空值 null,表示值未知。
-
SQL 允许在 insert 语句中指定属性(因此可不用考虑属性的排列顺序)。
insert into course(course_id, title,dept_name, credits) values ('CS-437', 'Database Systems', 'Comp.Sci', 4) ;
-
可在查询结果的基础上插入元组。
insert into instructor
select ID, name, dept_name, 18000 from student
where dept_name = 'Music' and tot_cred > 144 ; -
在执行插入之前先执行完 select 语句非常重要,若在执行 select 语句的同时执行插入:
insert into student
select * from student ;若student上没有主码约束,则👆请求可能会插入无数元组。若在插入前先完成 select 语句就可避免此问题。
若无主码约束,此请求会重新插入 student 中的第一个元组,产生该元组的第二份拷贝;由于此副本现在是student中的一部分,select 语句可能找到它,则第三份拷贝被插入到student中,如此无限循环。
3.9.3 更新
-
更新可在不改变整个元组的情况下改变其部分属性的值;SQL首先检查关系中的所有元组,看它们是否应该被更新,然后执行更新。
给工资低于平均数的教师涨5%工资:
update instructor
set salary = salary * 1.05
where salary < (select avg (salary) from instructor) ; -
update 语句中的 where 子句可以包含 select 语句的 where 子句中的任何合法结构(包括嵌套的 select)。
-
和 insert、delete 语句类似,update 语句中嵌套的 select 可引用待更新的关系。
-
SQL 提供 case 结构,可在一条 update 语句中执行两种更新,且避免更新次序引发的问题。
给工资超过 100000美元的教师涨3%工资,其余教师涨5%:
update instructor
set salary = case
where salary <= 100000 then salary * 1.05
else salary * 1.03
endcase 语句的一般格式 如下:
case when pred1 then result1 when pred2 then result2 ··· when predn then resultn else result0 end
-
标量子查询可用在 SQL 更新语句的 set 子句中。
把每个student元组的tot_cred属性值设为该生成功学完的课程(成绩既不是F也不是空)学分的总和。
update student S
set tot_cred = (
select sum (credits) from takes natural join course
where S.ID = takes.ID and takes.grade <> 'F' and takes.grade is not null) ;
总结

术语回顾

本文作者:Joey-Wang
本文链接:https://www.cnblogs.com/joey-wang/p/16057547.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步