SQL笔记

MARCUS_YANG

SQL基本概念

SQL(Structured Query Language)结构化查询语言,是关系数据库的标准语言特点:

SELECT Sno, Grade
FROM SC
WHERE Cno= '3'
ORDER BY Grade DESC;
//从表 SC 中选取学号 Sno 和成绩 Grade 满足条件课程号 Cno=“3”按照成绩 Gradel 降序排列

  • 综合统一:

    • 集数据定义语言(DDL),数据操纵语言(DML),数据控制语言(DCL)功能于一体。
    • 定义和修改、删除关系模式,定义和删除视图,插入数据,建立数据库;
    • 对数据进行增删改查
    • 数据库的重构和维护
    • 数据库安全性、完整性控制,以及事务控制
    • 嵌入式和动态SQL定义
  • 高度非过程化:SQL 只要提出“做什么”,无须了解存取路径。
  • 面向集合的操作方式:
    • 非关系数据模型采用面向记录的操作方式,操作对象是一条记录
    • 采用集合操作方式
    • 操作对象、查找结果可以是元组的集合
    • 一次插入、删除、更新操作的对象可以是元组的集合
  • 以同一种语法结构提供多种使用方式:独立使用和嵌入高级语言中
  • 语言简洁,易学易用
  • SQL支持关系数据库三级模式结构:
    • 基本表:

      • 本身独立存在的表
      • SQL 中一个关系就对应一个基本表
      • 一个(或多个)基本表对应一个存储文件
      • 一个表可以带若干索引
    • 存储文件:

      • 逻辑结构组成了关系数据库的内模式
      • 物理结构对用户来说是隐蔽的
    • 视图:

      • 用户可以在视图上再定义视图
      • 视图是一个虚表
      • 数据库中只存放视图的定义而不存放视图对应的数据
      • 从一个或几个基本表导出的表

贯彻这门课的三个样例表:

student table:

SNO 学号Sname 姓名Ssex 性别Sage 年龄Sdept 系17150011001MarcusMA21CS

Course表

Cno课程号Cname 课程名Cpno 先修课Ccredit 学分1数据库542数学NULL23信息系统144操作系统635数据结构746数据处理NULL27PASCAL64

学生课程表SC

Sno 学号Cno 课程号Grade 成绩171500110011100


数据定义

SQL 的数据定义功能:定义各种数据库的“对象”

  • 模式定义
  • 表定义
  • 视图定义
  • 索引定义
  • [ ]

定义模式:

example: 定义模式实际上定义了一个命名空间(或者说目录)

[例3.1] 为用户WANG定义一个学生-课程模式S-T

CREATE SCHEMA “S-T” AUTHORIZATION WANG;

[例3.2] CREATE SCHEMA AUTHORIZATION WANG;

该语句没有指定<模式名,<模式名隐含为<用户名

  • 在 CREATE SCHEMA 中可以接受 CREATETABLE CREATE VIEW 和 GRANT 子句。
  • [例3.3]为用户ZHANG创建了一个模式TEST,并且在其中定义一个表 TAB1CREATE SCHEMA TEST AUTHORIZATION ZHANGCREATE TABLE TAB1(COL1 SMALLINT,
    COL2 INT,
    COL3 CHAR(20),
    COL4 NUMERIC(10,3),
    COL5 DECIMAL(5,2)
    );

删除模式

DROP SCHEMA <模式名<CASCADE|RESTRICT

  • CASCADE删除模式的同时把该模式中所有的数据库对象全部删除
  • RESTRICT如果该模式中定义了下属的数据库对象(如表、视图等),则拒绝该删除语句的执行。仅当该模式中没有任何下属的对象时才能执行。

[例3.4] DROP SCHEMA ZHANG CASCADE;

删除模式ZHANG

同时该模式中定义的表TAB1也被删除

基本表的定义

  • 列级完整性约束条件:涉及相应属性列的完整性约束条件
  • 表级完整性约束条件:涉及一个或多个属性列的完整性约束条件
  • 如果完整性约束条件涉及到该表的多个属性列,则必须定义在表级上。

[例3.5] 建立“学生”表Student。学号是主码,姓名取值唯一。

CREATE TABLE Student(Sno CHAR(9) PRIMARY KEY,/* 列级完整性约束条件,Sno是主码*/
Sname CHAR(20) UNIQUE,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);


[例3.6 ] 建立一个“课程”表Course

CREATE TABLE Course(Cno CHAR(4) PRIMARY KEY,
Cname CHAR(40),
Cpno CHAR(4),/*先修课*/
Ccredit SMALLINT,
FOREIGN KEY (Cpno) REFERENCES Course(Cno)/*Cpno是外码,被参照表是Course,被参照列是Cno*/
);


[例3.7] 建立一个学生选课表SC

CREATE TABLE SC(Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY (Sno,Cno),/* 主码由两个属性构成,必须作为表级完整性进行定义*/
FOREIGN KEY (Sno) REFERENCES Student(Sno),/* 表级完整性约束条件,Sno是外码,被参照表是Student */
FOREIGN KEY (Cno)REFERENCES Course(Cno)/* 表级完整性约束条件, Cno是外码,被参照表是Course*/
);

数据类型

关系模型中“域”的概念:

MYSQL:https://www.runoob.com/mysql/mysql-data-types.html

作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。

类型大小范围(有符号)范围(无符号)用途TINYINT1 byte(-128,127)(0,255)小整数值SMALLINT2 bytes(-32 768,32 767)(0,65 535)大整数值MEDIUMINT3 bytes(-8 388 608,8 388 607)(0,16 777 215)大整数值INT或INTEGER4 bytes(-2 147 483 648,2 147 483 647)(0,4 294 967 295)大整数值BIGINT8 bytes(-9,223,372,036,854,775,808,9 223 372 036 854 775 807)(0,18 446 744 073 709 551 615)极大整数值FLOAT4 bytes(-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38)0,(1.175 494 351 E-38,3.402 823 466 E+38)单精度 浮点数值DOUBLE8 bytes(-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)双精度 浮点数值DECIMAL对DECIMAL(M,D) ,如果MD,为M+2否则为D+2依赖于M和D的值依赖于M和D的值小数值


日期和时间类型

表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

TIMESTAMP类型有专有的自动更新特性,将在后面描述。

类型大小 ( bytes)范围格式用途DATE31000-01-01/9999-12-31YYYY-MM-DD日期值TIME3'-838:59:59'/'838:59:59'HH:MM:SS时间值或持续时间YEAR11901/2155YYYY年份值DATETIME81000-01-01 00:00:00/9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和时间值TIMESTAMP41970-01-01 00:00:00/2038结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07YYYYMMDD HHMMSS混合日期和时间值,时间戳


字符串类型

字符串类型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。该节描述了这些类型如何工作以及如何在查询中使用这些类型。

类型大小用途CHAR0-255 bytes定长字符串VARCHAR0-65535 bytes变长字符串TINYBLOB0-255 bytes不超过 255 个字符的二进制字符串TINYTEXT0-255 bytes短文本字符串BLOB0-65 535 bytes二进制形式的长文本数据TEXT0-65 535 bytes长文本数据MEDIUMBLOB0-16 777 215 bytes二进制形式的中等长度文本数据MEDIUMTEXT0-16 777 215 bytes中等长度文本数据LONGBLOB0-4 294 967 295 bytes二进制形式的极大文本数据LONGTEXT0-4 294 967 295 bytes极大文本数据

注意:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。

修改基本表

  • ALTER TABLE <表名

    • [ADD[COLUMN] <新列名 <数据类型 [ 完整性约束 ] ]
    • [ADD <表级完整性约束]
    • [DROP [ COLUMN ] <列名 [CASCADE| RESTRICT] ]
    • [DROP CONSTRAINT<完整性约束名[ RESTRICT | CASCADE ] ]
    • [ALTER COLUMN <列名<数据类型 ] ;
    • ADD子句用于增加新列、新的列级完整性约束条件和新的表级完整性约束条件
    • DROP COLUMN子句用于删除表中的列
      • CASCAD:则自动删除引用了该列的其他对象
      • RESTRICT:如果该列引用了其他对象,则关系数据库解决删除
    • DROP CONSTRAINT子句用于删除指定的完整性约束条件
    • ALTER COLUMN子句用于修改原有的列定义,包括修改列名和数据类型
  • [例3.8] 向Student表增加“入学时间”列,其数据类型为日期型
    ALTER TABLE Student ADD S_entrance DATE;
  • [例3.9] 将年龄的数据类型由字符型(假设原来的数据类型是字符型)改为整数。
    ALTER TABLE Student ALTER COLUMN Sage INT;[例3.10] 增加课程名称必须取唯一值的约束条件。
    ALTER TABLE Course ADD UNIQUE(Cname);

删除基本表

  • DROP TABLE <表名[RESTRICT| CASCADE];

    • RESTRICT:删除表是有限制的。
    • CASCADE:删除该表没有限制。
  • [例3.11] 删除Student表
    DROP TABLE Student CASCADE;

索引

常见的索引:

  • 顺序文件上的索引
  • B+树索引
  • 散列(hash)索引
  • 位图索引

创建索引

CREATE [UNIQUE] [CLUSTER] INDEX <索引名

ON <表名(<列名[<次序][,<列名[<次序] ]…);

  • 升序:ASC(默认)
  • 降序:DESC

[例3.13] 为学生-课程数据库中的Student,Course,SC三个 表建立索引。Student表按学号升序建唯一索引,Course表 按课程号升序建唯一索引 , SC 表按学号升序和课程号降序 建唯一索引

CREATE UNIQUE INDEX Stusno ON Student(Sno);
CREATE UNIQUE INDEX Coucno ON Course(Cno);
CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC);

修改索引

ALTER INDEX<旧索引名RENAME TO<新索引名

例 3.149 将 SC 表的 SCno 索引名改为 Scsno

ALTER INDEX Scno RENAME TO Scsno

删除索引

DROP INDEX <索引名;

[例3.15] 删除Student表的Stusname索引

DROP INDEX Stusname;


数据查询_1

单表查询

一共有 6 个子句

  • SELECT选择基本表的行和列 ,初始状态下不去重复,

    • DISTINC 关键字可以去重
  • Group BY-HAVING (聚集函数)
  • order by 排序

SELECT子句

[例3.16] 查询全体学生的学号与姓名。

SELECT Sno,Sname
FROM Student;

[例3.18] 查询全体学生的详细记录

SELECT Sno,Sname,Ssex,Sage,Sdept
FROM Student;
或
SELECT *
FROM Student;

查询计算表达式:

[例3.19] 查全体学生的姓名及其出生年份

SELECT Sname,2020-Sage
FROM Student;

[例3.20] 查询全体学生的姓名、出生年份和所在的院系,要 求用小写字母表示系名。

SELECT Sname,'Year of Birth: ',2014-Sage,LOWER(Sdept)
FROM Student;

使用列别名改变查询结果的列标题:

SELECT Sname NAME,'Year of Birth:' BIRTH,2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT
FROM Student;

[例3.21] 查询选修了课程的学生学号。

SELECT DISTINCT Sno
FROM SC;

[例3.22] 查询计算机科学系全体学生的名单。

SELECT Sname
FROM Student
WHERE Sdept=‘CS’;

[例3.23]查询所有年龄在20岁以下的学生姓名及其年龄。

SELECT Sname,Sage
FROM Student
WHERE Sage < 20;

[例3.24]查询考试成绩有不及格的学生的学号。

SELECT DISTINCT Sno
FROM SC
WHERE Grade<60;

[例3.25] 查询年龄在20~23岁(包括20岁和23岁)之间的学生 的姓名、系别和年龄

SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;

[例3.26] 查询年龄不在20~23岁之间的学生姓名、系别和年龄

SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;

[例3.27]查询计算机科学系(CS)、数学系(MA)和信息 系(IS)学生的姓名和性别。

SELECT Sname, Ssex
FROM Student
WHERE Sdept IN ('CS','MA’,'IS' );

[ 例 3.28] 查询既不是计算机科学系 、 数学系 , 也不是信息系 的学生的姓名和性别。

SELECT Sname, Ssex
FROM Student
WHERE Sdept NOT IN ('CS','MA’,'IS' );

字符串匹配:

%:如a%b表示以a开头,以b结尾的任意长度的字符串

_:a_b表示以a开头,以b结尾的长度为3的任意字符串

[例3.29] 查询学号为201215121的学生的详细情况。

SELECT *
FROM Student
WHERE Sno LIKE ‘201215121';//WHERE Sno = ' 201215121 ';

[例3.30] 查询所有刘某学生的姓名、学号和性别。

SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname LIKE '刘%';

[例3.31] 查询姓"欧阳"且全名为三个汉字的学生的姓名。

SELECT Sname
FROM Student
WHERE Sname LIKE '欧阳__';

[例3.32] 查询名字中第2个字为"阳"字的学生的姓名和学号。

SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '__阳%';

[例3.33] 查询所有不姓刘的学生姓名、学号和性别。

SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname NOT LIKE '刘%';

[例3.34] 查询DB_Design课程的课程号和学分。

SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB_Design' ESCAPE ' ' ;

_转义表示_

[例3.35] 查询以"DB_"开头,且倒数第3个字符为 i的课程的 详细情况。

SELECT *
FROM Course
WHERE Cname LIKE 'DB_%i_ _' ESCAPE ' ' ;

[例3.36] 某些学生选修课程后没有参加考试,所以有选课记 录,但没 有考试成绩。查询缺少成绩的学生的学号和相应 的课程号。

SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL

[例3.37] 查所有有成绩的学生学号和课程号。

SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;

[例3.38] 查询计算机系年龄在20岁以下的学生姓名。

SELECT Sname
FROM Student
WHERE Sdept= 'CS' AND Sage<20;

[例3.27] 查询计算机科学系(CS)、数学系(MA)和信息系 (IS)学生的姓名和性别。

SELECT Sname, Ssex
FROM Student
WHERE Sdept IN ('CS','MA’,'IS' );

[ 例 3.28] 查询既不是计算机科学系 、 数学系 , 也不是信息系 的学生的姓名和性别。

SELECT Sname, Ssex
FROM Student
WHERE Sdept NOT IN ('IS','MA’,'CS' );

[例3.29] 查询学号为201215121的学生的详细情况。

SELECT *
FROM Student
WHERE Sno LIKE ‘201215121';

[例3.30] 查询所有姓刘学生的姓名、学号和性别。

SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname LIKE '刘%';

[例3.31] 查询姓"欧阳"且全名为三个汉字的学生的姓名。

SELECT Sname
FROM Student
WHERE Sname LIKE '欧阳__';

[例3.32] 查询名字中第2个字为"阳"字的学生的姓名和学号。

SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '__阳%';

[例3.33] 查询所有不姓刘的学生姓名、学号和性别。

SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname NOT LIKE '刘%';

[例3.34] 查询DB_Design课程的课程号和学分。

SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB_Design' ESCAPE ' ' ;

[例3.35] 查询以"DB_"开头,且倒数第3个字符为 i的课程的 详细情况。

SELECT *
FROM Course
WHERE Cname LIKE 'DB_%i_ _' ESCAPE ' ' ;

[例3.36] 某些学生选修课程后没有参加考试,所以有选课记 录,但没 有考试成绩。查询缺少成绩的学生的学号和相应 的课程号。

SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL //IS”不能用“=”代替

[例3.37] 查所有有成绩的学生学号和课程号。

SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;

[例3.38] 查询计算机系年龄在20岁以下的学生姓名。

SELECT Sname
FROM Student
WHERE Sdept= 'CS' AND Sage<20;

ORDER BY 子句

可以按一个或多个属性列排序

升序:ASC;降序:DESC;缺省值为升序

[例3.39]查询选修了3号课程的学生的学号及其成绩,查询结 果按分数降序排列。

SELECT Sno, Grade
FROM SC
WHERE Cno= ' 3 '
ORDER BY Grade DESC;

[例3.40]查询全体学生情况,查询结果按所在系的系号升序 排列,同一系中的学生按年龄降序排列。

SELECT *
FROM Student
ORDER BY Sdept, Sage DESC;

聚集函数

  • DISTINCT 去重
  • ALL 所有(默认)
  • 统计元组个数COUNT(*)
  • 统计一列中值的个数COUNT([DISTINCT|ALL] <列名)
  • 计算一列值的总和SUM([DISTINCT|ALL] <列名)
  • 计算一列值的平均值AVG([DISTINCT|ALL] <列名)
  • 求一列中的最大值和最小值:
    • MAX([DISTINCT|ALL] <列名)
    • MIN([DISTINCT|ALL] <列名)

[例3.41] 查询学生总人数。

SELECT COUNT(*)
FROM Student;

[例3.42] 查询选修了课程的学生人数。

SELECT COUNT(DISTINCT Sno)
FROM SC;

[例3.43] 计算1号课程的学生平均成绩。

SELECT AVG(Grade)
FROM SC
WHERE Cno= ' 1 ';

[例3.44] 查询选修1号课程的学生最高分数。

SELECT MAX(Grade)
FROM SC
WHERE Cno='1';

[例3.45 ] 查询学生201215012选修课程的总学分数。

SELECT SUM(Ccredit)
FROM SC,Course
WHERE Sno='201215012' AND SC.Cno=Course.Cno;

GROUP BY 子句:细化聚集函数的作用对象

[例3.46] 求各个课程号及相应的选课人数。

SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;

[例3.47] 查询选修了3门以上课程的学生学号。

SELECT Sno
FROM SC
GROUP BY Sno HAVING COUNT(Cno) 3;

[例3.48 ]查询平均成绩大于等于90分的学生学号和平均成绩

SELECT Sno, AVG(Grade)
FROM SC
GROUP BY Sno HAVING AVG(Grade)=90;

HAVING 短语与 WHERE 子句的区别:

  • 作用对象不同
  • WHERE 子句作用于基表或视图,从中选择满足条件的元组
  • HAVING 短语作用于组,从中选择满足条件的组

综合练习

[练习1] 列出计算机系姓刘的同学的信息,按照学号大小 排序

SELECT *
FROM Student
WHERE Sdept=‘CS’ AND Sname LIKE ‘刘%’
ORDER BY Sno;

[练习2] 按系并区分男女统计各系学生的人数、并按照人 数降序排序

SELECT Sdept, Ssex,COUNT(Sno)
FROM Student
GROUP BY Sdept,Ssex
ORDER BY COUNT(Sno) DESC;

数据连接

不像关系代数中“连接”是用一个特殊符号来表达的, 在 SQL中“连接”是用“连接条件”来表达的。

一般格式:[<表名1.]<列名1 <比较运算符 [<表名2.]<列名2

  • 等值连接
  • 自身连接
  • 外连接
  • 多表连接

等值连接

连接运算符为 “=”

[例 3.49] 查询每个学生及其选修课程的情况

SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno = SC.Sno;

  • 嵌套循环法(NESTED-LOOP)
  • 排序合并法(SORT-MERGE)
  • 索引连接(INDEX-JOIN)

[例 3.51 ]查询选修2号课程且成绩在90分以上的所有学生的学号和姓名。

SELECT Student.Sno, Sname
FROM Student, SC
WHERE Student.Sno=SC.Sno AND
SC.Cno=' 2 ' AND SC.Grade90;

自身连接

自身连接:一个表与其自己进行连接,是一种特殊的连接

!!!需要给表起别名以示区别

!!!由于所有属性名都是同名属性,因此必须使用别名前缀

[例 3.52]查询每一门课的直接先修课的名称

SELECT FIRST.Cname , SECOND.Cname
FROM Course FIRST, Course SECOND
WHERE FIRST.Cpno = SECOND.Cno;

外连接

  • 外连接操作以指定表为连接主体,将主体表中不满足连 接条件的元组一并输出
  • 普通连接操作只输出满足连接条件的元组

[例 3.49] 查询每个学生及其选修课程的情况

SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUT JOIN SC ON
(Student.Sno=SC.Sno);
//或
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student,SC
WHERE Student.Sno(+)=SC.Sno;

多表连接

[例3.54]查询每个学生的学号、姓名、选修的课程名及成绩

SELECT Student.Sno, Sname, Cname, Grade
FROM Student,SC,Course /*多表连接*/
WHERE Student.Sno = SC.Sno AND SC.Cno = Course.Cno;

嵌套查询

不相关子查询:

子查询的查询条件不依赖于父查询

由里向外逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。

相关子查询:

子查询的查询条件依赖于父查询

带 IN 谓词

[例 3.55] 查询与“刘晨”在同一个系学习的学生。

分步法:

① 确定“刘晨”所在系名

SELECT Sdept
FROM Student
WHERE Sname= ' 刘晨 ';

② 查找所有在CS系学习的学生。

SELECT Sno, Sname, Sdept
FROM  Student
WHERE Sdept= ' CS ';


将第一步查询嵌入到第二步查询的条件中:

SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept IN(SELECT Sdept
FROM Student
WHERE Sname= '刘晨'
);


自身连接法:

SELECT S1.Sno, S1.Sname,S1.Sdept
FROM Student S1,Student S2
WHERE S1.Sdept = S2.Sdept AND
S2.Sname = '刘晨';


[例 3.56]查询选修了课程名为“信息系统”的学生学号和姓名

SELECT Sno,Sname  //③ 最后在Student关系中取出Sno和Sname
FROM Student
WHERE Sno IN(SELECT Sno //② 然后在SC关系中找出选修了3号课程的学生学号FROM SC
WHERE Cno IN(SELECT Cno //① 首先在Course关系中找出“信息系统”的课程号,为3号FROM CourseWHERE Cname= '信息系统')
);

或:

SELECT Sno,Sname
FROM Student,SC,Course
WHERE Student.Sno = SC.Sno ANDSC.Cno = Course.Cno ANDCourse.Cname='信息系统';

带有比较运算符的子查询

[例 3.55] 查询与“刘晨”在同一个系学习的学生。

SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept=(SELECT Sdept/*由于一个学生只可能在一个系学习 , 用=代替*/
FROM Student
WHERE Sname= '刘晨');

[例 3.57 ]找出每个学生超过他选修课程平均成绩的课程号。(自身嵌套的例子)

SELECT Sno, Cno
FROM SC x
WHERE Grade =(SELECT AVG(Grade)FROM SC yWHERE y.Sno=x.Sno);

带有 ANY (SOME)或 ALL 谓词的子査询

  • ANY 大于子查询结果中的某个值
  • =ANY 大于等于子査询结果中的某个值
  • !=(或<) ANY 不等于子査询结果中的某个值
  • !=(或<) ALL 不等于子查询结果中的任何一个值

image-20200430001129003

[例 3.58] 查询非计算机科学系中比计算机科学系任意一个 学生年龄小的学生姓名和年龄

SELECT Sname,Sage
FROM Student
WHERE Sage < ANY (SELECT SageFROM StudentWHERE Sdept= 'CS')AND Sdept < 'CS' ;/*父查询块中的条件 */

或者使用聚集函数

SELECT Sname,Sage
FROM Student
WHERE Sage <(SELECT MAX(Sage)FROM StudentWHERE Sdept= 'CS')AND Sdept < 'CS ';

[例 3.59] 查询非计算机科学系中比计算机科学系所有学 生年龄都小的学生姓名及年龄。

SELECT Sname,Sage
FROM Student
WHERE Sage < ALL(SELECT SageFROM StudentWHERE Sdept= 'CS')AND Sdept < 'CS’;SELECT Sname,Sage
FROM Student
WHERE Sage <(SELECT MIN(Sage)FROM StudentWHERE Sdept= 'CS')AND Sdept <'CS';

带有EXISTS谓词的子查询

  • 带有EXISTS谓词的子查询产生逻辑真值“true”或逻辑假值“false”。
  • 由 EXISTS引出的子查询,其目标列表达式通常都用 *
  • 可以把带有全称量词的谓词转换为等价的带有存在量词的谓词:
  • 可以利用谓词演算将逻辑蕴涵谓词等价转换为:

[例 3.60]查询所有选修了1号课程的学生姓名。

SELECT Sname
FROM Student
WHERE EXISTS(SELECT *FROM SCWHERE Sno=Student.Sno AND Cno= ' 1 ');

[例 3.61] 查询没有选修1号课程的学生姓名。

SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *FROM SCWHERE Sno=Student.Sno AND Cno= ' 1 ');

[例 3.55]查询与“刘晨”在同一个系学习的学生。

SELECT Sno,Sname,Sdept
FROM Student S1
WHERE EXISTS(SELECT *FROM Student S2WHERE S2.Sdept = S1.Sdept AND S2.Sname = '刘晨');

[例 3.62] 查询选修了全部课程的学生姓名。

SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *FROM CourseWHERE NOT EXISTS(SELECT *FROM SCWHERE Sno= Student.SnoAND Cno= Course.Cno));

[例 3.63]查询至少选修了学生17150011001选修的全部课程的 学生号码。

用逻辑蕴涵表达该查询:

用P表示谓词 “学生201215122选修了课程y”

用q表示谓词 “学生x选修了课程y”

则上述查询为:

SELECT DISTINCT SCX.Sno
FROM SC SCX
WHERE NOT EXISTS(SELECT *FROM SC SCYWHERE SCY.Sno = '17150011001' ANDNOT EXISTS(SELECT *FROM SC SCZWHERE SCZ.Sno=SCX.Sno AND SCZ.Cno=SCY.Cno));

数据查询_2_

集合查询

  • 并操作UNION

    • UNION:将多个查询结果合并起来时,系统自动去掉重复元组(系统默认)
    • UNION ALL:将多个查询结果合并起来时,保留重复元组
  • 交操作INTERSECT
  • 差操作EXCEPT

!参加集合操作的各查询结果的列数必须相同;对应 项的数据类型也必须相同

[例 3.64] 查询计算机科学系的学生及年龄不大于19岁的学生。

SELECT *
FROM Student
WHERE Sdept= 'CS'UNIONSELECT *
FROM Student
WHERE Sage<=19;

[例 3.65] 查询选修了课程1或者选修了课程2的学生。

SELECT Sno
FROM SC
WHERE Cno=' 1 'UNIONSELECT Sno
FROM SC
WHERE Cno= ' 2 ';

[例3.66] 查询计算机科学系的学生与年龄不大于19岁的学生 的交集。

SELECT *
FROM Student
WHERE Sdept='CS'INTERSECTSELECT *
FROM Student
WHERE Sage<=19

[例 3.66] 实际上就是查询计算机科学系中年龄不大 于19岁的学生。

SELECT *
FROM Student
WHERE Sdept= 'CS' AND Sage<=19;

[例 3.67]查询既选修了课程1又选修了课程2的学生。

SELECT Sno
FROM SC
WHERE Cno=' 1 'INTERSECTSELECT Sno
FROM SC
WHERE Cno='2 ';SELECT Sno
FROM SC
WHERE Cno=' 1 ' AND Sno IN(SELECT SnoFROM SCWHERE Cno=' 2 ');//下面是一个典型的错误例子
SELECT Sno
FROM SC
WHERE Cno='1' and Cno='2'

[例 3.68] 查询计算机科学系的学生与年龄不大于19岁的 学生的差集。

SELECT *
FROM Student
WHERE Sdept='CS'EXCEPTSELECT *
FROM Student
WHERE Sage <=19;SELECT *
FROM Student
WHERE Sdept= 'CS' AND Sage19;

数据更新

插入数据

插入元组

INSERT INTO <表名 [(<属性列1[,<属性列2 …)]

VALUES (<常量1 [,<常量2]… );

INTO 子句

四种情况:

  • 属性列的顺序可与表定义中的顺序不一致
  • 指定要插入数据的表名及属性列
  • 没有指定属性列:表示要插入的是一条完整的元组,且 属性列属性与表定义中的顺序一致
  • 指定部分属性列:插入的元组在其余属性列上取空值

VALUES子句

提供的值必须与INTO子句匹配

[例3.69]将一个新学生元组(学号:201215128;姓名:陈冬; 性别:男;所在系:IS;年龄:18岁)插入到Student表中。

INSERT INTO Student (Sno,Sname,Ssex,Sdept,Sage)
VALUES ('17150011001','陈扬','男','CS',21);

[例3.71] 插入一条选课记录( '200215128','1 ')。

INSERT INTO SC(Sno,Cno)
VALUES ('201215128 ',' 1 ');

或:

INSERT INTO SC
VALUES (' 201215128 ',' 1 ',NULL);

[例3.70]将学生张成民的信息插入到Student表中。

INSERT INTO Student
VALUES ('201215126','张成民','男’,18,'CS');

在 student 后没有定义每个元素的意义,就必须和表一一对应

插入子查询结果

INSERT INTO <表名 [(<属性列1 [,<属性列2… )]子查询;

[例3.72] 对每一个系,求学生的平均年龄,并把结果存入数据库

建表:

CREATE TABLE Dept_age(Sdept CHAR(15)/*系名*/Avg_age SMALLINT);/*学生平均年龄*/

插入数据:

INSERT INTO Dept_age(Sdept,Avg_age)SELECT Sdept,AVG(Sage)FROM StudentGROUP BY Sdept;

插入数据的时候会检测完整性:

  • 实体完整性
  • 参照完整性
  • 用户定义的完整性
    • NOT NULL约束
    • UNIQUE约束
    • 值域约束

修改数据

UPDATE <表名

SET <列名=<表达式[,<列名=<表达式]…

[WHERE <条件];

三种修改方式:

  • 修改某一个元组的值
  • 修改多个元组的值
  • 带子查询的修改语句

[例3.73] 将学生201215121的年龄改为22岁

UPDATE Student
SET Sage=22
WHERE Sno=' 201215121 ';

[例3.74] 将所有学生的年龄增加1岁。

UPDATE Student
SET Sage= Sage+1;

[例3.75] 将计算机科学系全体学生的成绩置零。

UPDATE SC
SET Grade=0
WHERE Sno IN(SELETE SnoFROM StudentWHERE Sdept= 'CS' );

更新数据同样会检测完整性约束

删除数据

DELETE FROM <表名

[WHERE <条件];

删除指定表中满足WHERE子句条件的元组,无该子句将会删除表中的全部元组

三种删除方式:

  • 删除某一个元组的值
  • 删除多个元组的值
  • 带子查询的删除语句

[例3.76] 删除学号为201215128的学生记录。

DELETE FROM Student
WHERE Sno= 201215128 ';

[例3.77] 删除所有的学生选课记录。

DELETE FROM SC;

[例3.78] 删除计算机科学系所有学生的选课记录。

DELETE
FROM SC
WHERE Sno IN(SELETE SnoFROM StudentWHERE Sdept= 'CS') ;

空值的处理

空值不等于 NULL,表示本来应该有一个值,但是现在未知

判断一个属性的值是否为空值,用IS NULL或IS NOT NULL来表示。

[例 3.81]找出漏填了性别或者年龄信息的记录

SELECT *
FROM Student
WHERE Ssex IS NULL OR Sage IS NULL ;

约束条件:

  • 有NOT NULL约束条件的不能取空值
  • 加了UNIQUE限制的属性不能取空值
  • 码属性不能取空值

[例3.82] 找出选修1号课程的不及格的学生。

SELECT Sno
FROM SC
WHERE Grade < 60 AND Cno='1';

[例 3.83] 选出选修1号课程的不及格的学生以及缺考的学生。

SELECT Sno
FROM SC
WHERE Cno='1' AND (Grade<60 OR Grade IS NULL);

视图view

视图是定义在基本表之上的虚表,是从一个或几个基本表(或视图)导出的表

  • 只存放视图的定义,不存放视图对应的数据
  • 基表中的数据发生变化,从视图中查询出的数据也随之改变

视图的定义

CREATE VIEW

<视图名 [(<列名 [,<列名]…)]

AS <子查询

[WITH CHECK OPTION];

  • WITH CHECK OPTION:子查询中的条件表达式约束
  • 子查询可以是任意的SELECT语句
  • 关系数据库管理系统执行 CREATE VIEW 语句时只是把视图定义存入数据字典,并不执行其中的SELECT 语句。
  • 对视图查询时,按视图的定义从基本表中将数据查出。
  • 若一个视图是从单个基本表导出的,并且只是去掉了基本表的某些行和某些列,但保留了主码,我们称这类视图为行列子集视图

[例3.84] 建立信息系学生的视图。

CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS';

[例3.85]建立信息系学生的视图,并要求进行修改和插入 操作时仍需保证该视图只有信息系的学生 。

CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept= 'IS'
//对该视图进行插入、修改和删除操作会自动加上Sdept='IS'的条件。
WITH CHECK OPTION;

[例3.86] 建立信息系选修了1号课程的学生的视图(包括 学号、姓名、成绩)

CREATE VIEW IS_S1(Sno,Sname,Grade)
AS
SELECT Student.Sno,Sname,Grade
FROM Student,SC
WHERE Sdept= 'IS' ANDStudent.Sno=SC.Sno ANDSC.Cno= '1';

[例3.87] 建立信息系选修了1号课程且成绩在90分以上的学生的视图。

在视图上定义视图(套娃)

CREATE VIEW IS_S2
AS
SELECT Sno,Sname,Grade
FROM IS_S1
WHERE Grade=90;

[例3.88] 定义一个反映学生出生年份的视图。

CREATE VIEW BT_S(Sno,Sname,Sbirth)
AS
SELECT Sno,Sname,2014-Sage
FROM Student;

[例3.89] 将学生的学号及平均成绩定义为一个视图

[聚集函数]

CREAT VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;

[例3.90]将Student表中所有女生记录定义为一个视图

CREATE VIEW F_Student(F_Sno,name,sex,age,dept)
AS
SELECT *
FROM Student
WHERE Ssex=‘女’;
//* 有可能导致在后面修改 student 表的时候视图出错

删除视图

DROP VIEW <视图名[CASCADE];

  • 该语句从数据字典中删除指定的视图定义
  • 如果该视图上还导出了其他视图,使用CASCADE级联删除语句
  • 删除基本表时需要DROP由该表导出的视图

[例3.91 ] 删除视图BT_S和IS_S1

DROP VIEW BT_S;/*成功执行*/DROP VIEW IS_S1;/*拒绝执行*/
DROP VIEW IS_S1 CASCADE;/*成功执行*/

查询视图

  • 查询视图与查询基本表相同

[例3.92] 在信息系学生的视图中找出年龄小于20岁的学生。

SELECT  Sno,Sage
FROM IS_Student
WHERE Sage<20;

[例3.93] 查询选修了1号课程的信息系学生

SELECT IS_Student.Sno,Sname
FROM IS_Student,SC
WHERE IS_Student.Sno =SC.Sno AND SC.Cno= '1';

[例3.94]在S_G视图中查询平均成绩在90分以上的学生学号 和平均成绩

CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;SELECT *
FROM S_G
WHERE Gavg=90;

SELECT *
FROM (SELECT Sno,AVG(Grade)FROM SCGROUP BY Sno) AS S_G(Sno,Gavg)
WHERE Gavg=90;

更新视图

[例3.95] 将信息系学生视图IS_Student中学号”201215122”的学生姓名改为”刘辰”。

UPDATE IS_Student
SET Sname= '刘辰'
WHERE Sno= ' 201215122 ';UPDATE Student
SET Sname= '刘辰'
WHERE Sno= ' 201215122 ' AND Sdept= 'IS';

[例3.96] 向信息系学生视图IS_Student中插入一个新的学生记录,其中学号为”201215129”,姓名为”赵新”,年龄 为20岁

INSERT
INTO IS_Student
VALUES(‘201215129’,’赵新’,20);INSERT
INTO Student(Sno,Sname,Sage,Sdept)
VALUES('200215129','赵新',20,'IS' );

[例3.97]删除信息系学生视图IS_Student中学号为”201215129”的记录

DELETE
FROM IS_Student
WHERE Sno= ' 201215129 ';DELETE
FROM Student
WHERE Sno= ' 201215129 ' AND Sdept= 'IS';

注意!聚集函数的视图在修改的时候聚集函数那一列是不可更新的

UPDATE S_G
SET Gavg=90
WHERE Sno= ‘201215121’;
//以上为反例

  • 允许对行列子集视图进行更新
  • 两个以上基本表导出视图原则上也不允许更新
  • 若视图的字段来自集函数,则此视图不允许更新。
  • 若视图定义中含有 GROUP BY 子句,则此视图不允许更新。
  • 若视图定义中含有 DISTINCT 短语,则此视图不允许更新 。
  • 若视图定义中有嵌套查询,并且内层查询的子句中涉及的表也是FROM导出该视图的基本表,则此视图不允许更新

sql删除元组_SQL笔记相关推荐

  1. sql删除元组_Lecture #02: 中级SQL

    本专栏是对CMU15445的笔记的翻译,原文地址:https://15445.courses.cs.cmu.edu/fall2020/notes/02-advancedsql.pdf 1 关系语言 在 ...

  2. sql语句截断_SQL Server中SQL截断和SQL删除语句之间的区别

    sql语句截断 We get the requirement to remove the data from the relational SQL table. We can use both SQL ...

  3. sql删除表中重复记录_SQL从SQL表中删除重复行的不同方法

    sql删除表中重复记录 This article explains the process of performing SQL delete activity for duplicate rows f ...

  4. sql删除表结构_SQL删除表

    sql删除表结构 In a real-time situation, there are scenarios when we would like to remove the table from t ...

  5. SQL常用用法相关笔记

    SQL常用用法相关笔记 1).----CAST和CONVERT的用法 SQL中的cast和convert都是用来将一种数据类型的表达式转换为另一种数据类型的表达式. CAST和CONVERT提供相似的 ...

  6. SQL及Excel函数笔记2022

    @[TOC](SQL及Excel函数笔记2022) Excel函数 使用场景:OA单据没有对应类型编码code 需要在表格中快速匹配出想要的输出可以使用一下IF函数 Excel if 公式使用 =IF ...

  7. SQL删除空格Trim函数(RTrim、LTrim)与<trim prefix=““ suffix=““ suffixOverrides=““ prefixOverrides=““></trim>

    一.SQL删除数据空格函数(Trim.RTrim.LTrim) 1.Trim()函数:前后空格 用来删除数据左右两边(开始和结尾处)的空格. 2.RTrim()函数:后面空格 用来删除数据右边(结尾处 ...

  8. SQL数据库教程-学习笔记2

    SQL数据库教程-学习笔记2 文章目录 SQL数据库教程-学习笔记2 三.DML语言的学习 1.插入语句:insert into 2.修改语句:update 3.删除语句:delete 4.练习题 四 ...

  9. sql查询语句DQL笔记

    RDBMS指关系型数据管理库,全称为Relational Database Management System RDBMS是SQL的基础 SQL是一门ANSI(American National St ...

  10. sql删除无人借阅的书_查找,下载,借阅,租赁和购买电子书的最佳网站

    sql删除无人借阅的书 So, you've got yourself an eBook reader, smartphone, tablet, or other portable device an ...

最新文章

  1. Sql语句查询 显示序号
  2. C++高级程序员基本技能你都具备吗?
  3. CentOS 初体验五: SSH远程连接
  4. IDEA 热部署 仅支持jdk1.6,1.7
  5. php如何操作mysql数据库代码_php如何操作mysql数据库的类(附代码)
  6. 飞鸽传书文件传输实现原理
  7. java方法、方法重载
  8. Oracle PL/SQL进阶
  9. Docker和容器简介
  10. 同学借我钱好几年了,还是个包工头,没打欠条不讲还钱事,怎么办?
  11. 不是一流大学毕业,却通过自学软件测试,进了阿里年薪初始22K
  12. WinEdt LaTex(一)—— hello world!
  13. scala和java集合的区别_Scala中Array和List的区别
  14. Python之深入解析Numpy的高级操作和使用
  15. audio接线图解_图文:主板跳线(排线)连接技巧HD AUDIO连线接法
  16. 阅读心得1:《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践 》
  17. windowsxp最新版本_9102 年还用 Windows XP 是怎样的体验?
  18. 区块链及相关密码学技术
  19. 基于SpringBoot+Vue前后端分离的在线教育平台项目
  20. SEO外链收录:锚文本外链代发排名

热门文章

  1. 在未来的多云世界中,选择云服务提供商,需要考虑什么?
  2. 4.1%的利率,100万贷款,30年还款,我们每月能少还多少房贷呢
  3. 为防泄密 新加坡政府将断掉公务员的网络连接
  4. OpenSTF手机设备管理平台-------二次开发
  5. 古巨蜥好几吨重,但在我们智人祖先面前也是枉然 | 袁硕 一席第449位讲者
  6. 360随身wifi作为无线网卡使用(在电脑有线网卡和无线网卡都没有的情况下)
  7. 连接局域网打印机简易教程
  8. 我们把计算机硬件系统和软件系统称为,中国大学MOOC:\我们把计算机硬件系统和软件系统总称为( )。\;...
  9. 观察者模式(行为型)
  10. 【工具笔记】java 中文替换,用于简单的中文替换脱敏加密,且保留模糊查询特性