当前位置: 首页 > news >正文

数据库 - SQL

参考友情链接QAQ,写的很好:快速入门SQL

1. 模式

1.1 创建模式

-- 为用户 WANG 定义一个 学生-课程 模式 "S-T"
CREATE SCHEMA "S-T" AUTORIZATION WANG;-- 模式名默认为用户名 WANG
CREATE SCHEMA AUTORIZATION WANG;

1.2 删除模式

-- CASCADE(级联):删除模式同时把该模式下所有数据库对象删除;
DROP SCHEMA TEST CASCADE;-- RESTRICT(限制):如果该模式中定义了数据库对象,则拒绝执行;
-- RESTRICT 为缺省值;
DROP SCHEMA TEST RESTRICT;

2. 基本表

2.1 定义基本元素

数据类型

数据类型表示内容
CHAR(n)长度为n的字符型
VARCHAR(n)最大长度为n的变长字符型
NUMBER(n)长度为n的数字型
INT长整型(4B)
SMALLINT短整型(4B)
BIGINT大整型(8B)
FLOAT(n)精度至少为n位的浮点数
DATE日期,格式为YYYY-MM-DD
TIME时间,格式为HH:MM:SS

列级完整性约束

约束条件意义
PRIMARY KEY主码(元素唯一不能重复):当只有一个主码时,可直接在对应的属性列标注
NOT NULL非空:表示该属性列不能取空值
UNIQUE唯一值:表示该属性列只能取唯一值
CHECK检查:检查该列是否满足某个条件,比如CHECK(某属性>20)

表级完整性约束

约束条件意义
PRIMARY KEY(列名1,…,列名n)多个主码:当主码由多个属性构成时,
必须作为表级完整性定义
FOREIGN KEY(列名1) REFERENCES 被参照表(列名1)外码:被参照的列必须是 PRIMARY KEY
或 UNIQUE 约束 的列,
本表所有值来源于被参照的列

2.2 创建基本表

-- 当主码为单一属性,PRIMARY KEY 约束与 NOT NULL+UNIQUE 等效
CREATE TABLE Student(Sno CHAR(5) NOT NULL UNIQUE,Sname CHAR(20) UNIQUE,Ssex CHAR(2),Sage INT,Sdept CHAR(15),PRIMARY KEY(Sno));-- 当主码为多属性,主码只能用 PRIMARY KEY 表级完整性约束
CREATE TABLE SC(Sno CHAR(5),Cno CHAR(3),Grade INT,PRIMARY KEY(Sno, Cno),FOREIGN KEY(Sno) REFERENCES Student(Sno),FOREIGN KEY(Cno) REFERENCES Course(Cno)); 

2.3 删除基本表

-- 级联,删除基本表的同时,相关依赖对象(视图,索引)一起删除
DROP TABLE Student CASCADE;-- 限制,欲删除的表不能被其他表约束,也不能存在依赖对象
DROP TABLE Student RESTRICT;

2.4 修改基本表

-- 向 Student 表增加“入学时间”列,数据类型为 DATE
ALTER TABLE Student ADD entrance DATE;-- 删除 entrance 列
ALTER TABLE Student DROP entrance;-- 将年龄数据类型改为半字长整数
ALTER TABLE Student ALTER COULUMN Sage SMALLINT;-- 删除/增加学生姓名必须取唯一值的约束
ALTER TABLE Student ADD/DROP UNIQUE(Sname);

2.5 索引

创建索引

-- Student 表按学号升序建单一索引
CREATE UNIQUE INDEX Stusno ON Student(Sno ASC);-- Student 表按年龄降序建普通索引
CREATE INDEX Stusage ON Student(Sage DESC);-- Course 表按课程号升序建单一索引,ASC 为缺省值
CREATE UNIQUE INDEX Cuncno ON Course(Cno);-- SC 表按学号升序和课程号降序建单一索引
CREATE UNIQUE INDEX SCno ON SC(Sno, Cno DESC);-- 在 Student 表的 Sname 列上建立一个聚簇索引,按 Sname 升序
CREATE CLUSTER INDEX Stusname ON  Student(Sname);

删除索引

-- 删除 Student 表的 Stusname 索引
DROP INDEX Stusname;

3. 单表查询

  • 需要用到的三张基本表:
  • 学生表 Student(Sno,Sname,Ssex,Sage,Sdept)

Sno

Sname

Ssex

Sage

Sdept

95001

李勇

20

CS

95002

刘晨

19

IS

95003

王敏

18

MA

95004

张立

19

IS

  • 课程表: Course(Cno,Cname,Cpno,Ccredit)

Cno

Cname

Cpno

Ccredit

1

数据库

5

4

2

数学

NULL

2

3

信息系统

1

4

4

操作系统

6

3

5

数据结构

7

4

6

数据处理

NULL

2

7

PASCAL语言

6

4

  • 学生选课表: SC(Sno,Cno,Grade)

Sno

Cno

Grade

95001

1

92

95001

2

65

95001

4

88

95002

2

90

95002

5

73

3.0 SQL 查询逻辑执行顺序

-- 从哪查 -> 过滤行 -> 分组 -> 过滤组 -> 选择数据 -> 选择排列顺序 
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY

3.1 SELECT

-- 查询全体学生的学号和姓名
SELECT Sno, Sname
FROM Student;-- 查询全体学生全部信息
SELECT *
FROM Student;-- 表达式,列别名
SELECT Sname NAME, 'Year of Birth:' BIRTH, 2025-Sage BIRTHDAY, LOWER(Sdept) DEPARTMENT
FROM Student;-- 去重:查询选修了课程的学生学号
SELECT DISDINCT Sno
FROM SC;-- DISDINCT 作用于所有目标列:查询选修各门课程的各种成绩
SELECT DISDINCT Cno, Grade
FROM SC;

3.2 WHERE(Step1 过滤行)

  • 比较运算符
-- 查询计算机系全体学生信息
SELECT *
FROM Student
WHERE Sdept='CS';-- 查询所有年龄在 20 岁以下的学生姓名和年龄
SELECT Sname, Sage
FROM Student
WHERE Sage < 20;
  • 确定范围
-- 查询所有年龄在 20~23 的学生姓名和年龄
SELECT Sname, Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;
  • 确定集合
-- 查询 IS,MA,CS 系学生姓名和性别
SELECT Sname, Ssex
FROM Student
WHERE Sdept IN ('IS','MA','CS');-- 查询不是 IS,MA,CS 系学生姓名和性别
SELECT Sname, Ssex
FROM Student
WHERE Sdept NOT IN ('IS','MA','CS');
  • 字符串匹配
-- 通配符:% 代表任意长度,_ 代表单个字符
-- 转义字符:ESCAPE'<换码字符>'-- 查询学号为 95001 的学生信息
SELECT *
FROM Student
WHERE Sno LIKE 95001;-- 查询姓名中第二个字为“阳”的学生姓名和学号
SELECT Sname, Sno
FROM Student
WHERE Sname LIKE '_阳%';-- 查询所有不姓刘的学生姓名
SELECT Sname
FROM Student
WHERE Sname NOT LIKE '刘%';-- 查询以“DB_”开头,倒数第三个字符为 i 的课程信息
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i__' ESCAPE'\';
  • 涉及空值
-- 使用谓词 IS NULL / IS NOT NULL
-- 查询缺少成绩的学生的学号和课程号
SELECT Sno, Cno
FROM SC
WHERE Grade IS NULL;
  • 多重条件
-- 优先级:NOT > AND > OR,可以用括号改变优先级
-- 查询计算机系 20 岁以下学生姓名
SELECT Sname
FROM Student
WHERE Sdept='CS' AND Grade<20;-- 查询 IS,MA,CS 系学生姓名和性别
SELECT Sname, Ssex
FROM Student
WHERE Sdept='IS' OR Sdept='MA' OR Sdept='CS';

3.3 ORDER BY

-- 查询选修了 3 号课程的学生的学号和成绩,结果按分数降序排列
SELECT Sno, Grade
FROM SC
WHERE Cno='3'
ORDER BY Grade DESC;-- 查询全体学生信息,结果按系名升序排列,同系按年龄降序排列
SELECT *
FROM Student
ORDER BY Sdept, Sage DESC;

3.4 集函数

  • 集函数可以出现在:SELECT、HAVING、ORDER BY、子查询中;
  • 集函数不能出现在:WHERE、GROUP BY 中直接使用;
  • 有无 GROUP BY 的区别:
    • 有 GROUP BY:按组聚合,返回多行;
    • 无 GROUP BY:全局聚合,返回单行;

-- 查询学生总人数
SELECT COUNT(*)
FROM Student;-- 查询选修了课程的总人数,用 DISTINCT 避免重复
SELECT COUNT(DISTINCT Sno)
FROM SC-- 查询选修了 1 号课程的学生最高分
SELECT MAX(Grade)
FROM SC
WHERE Cno='1';-- 查询学生 95002 选修课程的总学分
SELECT SUM(Ccredit)
FROM SC, Course
WHERE Sno='95002' AND SC.Sno=Course.Sno;

3.5 GROUP BY - HAVING(Step2 过滤组)

  • 使用GROUP BY子句后,SELECT子句的列名列表中只能出现分组属性和集函数;
  • WHERE 过滤行,HAVING 过滤组,先 WHERE 后 GROUP BY 再 HAVING;
-- 求各个课程号及相应的选课人数
SELECT Cno, COUNT(Sno)
FROM SC
GROUP BY Cno;-- 查询选修了超过 3 门课程的学生学号
SELECT Sno
FROM SC
GROUP BY Sno HAVING COUNT(*)>3;-- 查询有多于 3 门课程是 90 分以上的学生学号及课程数
SELECT Sno, COUNT(*)
FROM SC
WHERE Grade>90                    -- 先筛成绩 90 分以上的记录
GROUP BY Sno HAVING COUNT(*)>3;   -- 再筛课程数大于 3 的学生

4. 连接查询

4.1 两表连接

-- 查询每个学生及其选修课信息
SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno=SC.Sno;

4.2 自身连接

-- 查询每一门课的间接先修课,需要给表起别名
SELECT FIRST.Cno, SECOND.Cpno
FROM Course FIRST, Course SECOND
WHERE FIRST.Cpno=SECOND.Cno;

4.3 外连接

  • 左外连接保留左表的所有记录,并尽可能地匹配右表中的记录 右外连接保留右表的所有记录,并尽可能地匹配左表中的记录
  • 将悬浮元组保留在结果关系中,没有属性值的位置填上NULL;
  • SELECT 列名 FROM 表名1 LEFT OUTER JOIN 表名2 ON(连接条件)
  • SELECT 列名 FROM 表名1 RIGHT OUTER JOIN 表名2 ON(连接条件)
-- 查询每个学生及其选修课程的情况
SELECT Student.*, Cno, Grade
FROM Student LEFT OUTER JOIN SC
ON Student.Sno=SC.Sno-- 或
SELECT Student.*, Cno, Grade
FROM Student LEFT OUTER JOIN SC
USING(Sno)

4.4 复合条件连接

-- 查询选修 2 号课程且成绩在 90 以上的学生的学号和姓名
SELECT Student.Sno, Student.Sname
FROM Student, SC
WHERE Student.Sno=SC.Sno AND -- 连接条件SC.Cno='2' AND         -- 选择条件SC.Grade>=90;          -- 选择条件-- 查询每个学生的学号,姓名,选修的课程名及成绩
SELECT Student.Sno, Sname, Cname, Grade
FROM Student, SC, Course
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno;     -- 三张表需要两个连接条件 

5. 嵌套查询(两层 for 循环)

  • 子查询不能使用 ORDER BY 子句;

5.1 IN 子查询

-- 查询与“刘晨”在同一个系学习的学生(学号,姓名,系别)-- step1. 确定“刘晨”所在系名
SELECT Sdept
FROM Student
WHERE Sname='刘晨';-- step2. 查找所有在 IS 系学习的学生
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept='IS';-- 嵌套
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept IN(SELECT SdeptFROM StudentWHERE Sname='刘晨');
-- 查询选修了课程名为“数据库”的学生学号和姓名
SELECT Sno, Sname
FROM Student
WHERE Sno IN                    -- 最后在 Student 查询(SELECT SnoFROM SCWHERE Cno IN               -- 再在 SC 找选修了该课程的学生学号(SELECT CnoFROM CourseWHERE Cname='数据库')  -- 先在 Course 找“数据库”课程号

5.2 比较运算符子查询

  • 若内层查询返回单值,可用比较运算符;
-- 查询与“刘晨”在同一个系学习的学生
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept =(SELECT SdeptFROM StudentWHERE Sname='刘晨');
  • 同表关联要别名,先写逻辑后关联;
-- 找出每个学生超过他选修课平均分的课程号
SELECT Sno, Cno
FROM SC X
WHERE Grade >= (SELECT AVG(Grade)FROM SC Y            -- 相关子查询,取别名WHERE Y.Sno=X.Sno)

5.3 ANY / ALL 子查询

  • ANY:某些值;ALL:所有值;
-- 查询其他系中比IS系某些学生年龄小的学生姓名和年龄
SELECT Sname, Sage
FROM Student
WHERE Sage < ANY(SELECT SageFROM StudentWHERE Sdept='IS') -- 先找出IS系中所有年龄构成的集合AND Sdept<>'IS';-- 也可以用集函数实现
SELECT Sname, Sage
FROM Student
WHERE Sage < (SELECT MAX(Sage)FROM StudentWHERE Sdept='IS') AND Sdept<>'IS';-- 查询其他系中比IS系所有学生年龄小的学生姓名和年龄
SELECT Sname, Sage
FROM Student
WHERE Sage < ALL(SELECT SageFROM StudentWHERE Sdept='IS') AND Sdept<>'IS';-- 也可以用集函数实现
SELECT Sname, Sage
FROM Student
WHERE Sage < (SELECT MIN(Sage)FROM StudentWHERE Sdept='IS') AND Sdept<>'IS';

5.4 EXISTS 子查询

  • EXISTS 为存在量词,对应 NOT EXISTS;
  • EXISTS 子查询不返回任何数据,结果非空返回 true,结果为空返回 false;
-- 查询所有选修了 1 号课程的学生姓名
SELECT Sname
FROM Student
WHERE EXISTS(SELECT *           -- 由EXISTS引出的子查询,其目标列表达式通常都用*FROM SCWHERE Sno=Student.Sno AND Cno='1') -- 找到第一条匹配就返回-- 查询没有选修 1 号课程的学生姓名
SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *           FROM SCWHERE Sno=Student.Sno AND Cno='1') 
-- 查询选修了全部课程的学生(等价于不存在一门课没有选修)
SELECT Sname
FROM Student
WHERE NOT EXISTS(SELECT *                 -- 对课程号进行对比,匹配是否有没选修的课程号FROM CourseWHERE NOT EXISTS(SELECT *             -- 查询该学生选修了的课程号FROM SCWHERE Sno=Student.Sno AND Cno=Course.Cno));

6. 集合查询

6.1 并操作(UNION)

-- 查询CS系的学生和年龄不大于19的学生
SELECT *
FROM Student
WHERE Sdept='CS'
UNION
SELECT *
FROM Student
WHERE Sage<=19;-- 法二:单表查询
SELECT *
FROM Student
WHERE Sdept='CS' OR Sage<=19;

6.2 交操作(INTERSECT)

-- 查询选修了课程1和课程2的学生学号
SELECT Sno
FROM SC
WHERE Cno='1'
INTERSECT
SELECT Sno
FROM SC
WHERE Cno='2';-- 法二:连接查询(SC自身连接)
SELECT Sno
FROM SC X, SC Y
WHERE X.Sno=Y.Sno AND X.Cno='1' AND Y.Cno='2';

6.3 查操作(EXCEPT)

-- 查询CS系年龄不大于19岁的学生学号
SELECT Sno
FROM Student
WHERE Sdept='CS'
EXCEPT
SELECT Sno
FROM Student
WHERE Sage>19;-- 法二:单表查询
SELECT Sno
FROM Student
WHERE Sdept='CS' AND Sage<=19;

7. 数据更新

7.1 INSERT 插入

插入单个元组

-- 插入一个新学生信息
INSERT
INTO Student
VALUES('95020','陈冬','男',18,'IS');-- 插入一个选课记录('95020','1')
INSERT
INTO SC(Sno, Cno)
VALUES('95020','1')   -- Grade 取空

插入子查询结果

-- 对每一个系,求学生平均年龄,并存入数据库
INERT
INTO Deptage(Sdept, Avgage)
SELECT Sdept, AVG(Sage)
FROM Student
GROUP BY Sdept;

7.2 UPDATE 修改

-- 将学生95001的年龄改为22岁
UPDATE Student
SET Sage=22
WHERE Sno='95001';-- 将IS系所有学生的年龄增加1岁
UPDATE Student
SET Sage=Sage+1
WHERE Sdept='IS';-- 将CS系所有学生成绩清零
UPDATE SC
SET Grade=0
WHERE Sno IN(SELECT SnoFROM StudentWHERE Sdept='CS');

7.3 DELETE 删除

-- 删除学号95019的学生记录
DELETE
FROM Student
WHERE Sno='95019';-- 删除2号课程所有选课记录
DELETE
FROM SC
WHERE Cno='2';-- 删除所有选课记录
DELETE
FROM SC-- 删除CS系所有学生的选课记录
DELETE
FROM SC
WHERE Sno IN(SELECT SnoFROM StudentWHERE Sdept='CS');

8. 视图

8.1 建立视图

  • 若添加WITH句,则表示对视图进行增删改时要满足子查询中的条件表达式;
  • 行列子集视图:由单个基本表导出,仅去掉了基本表的某些行和某些列,但保留了主码;

-- 建立IS系学生视图
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS';
WITH CHECK OPTION;   -- 如果要求透过该视图的更新操作只涉及IS系学生,需要加这句-- 更新后每一行都应满足 Sdept='IS' 条件-- 建立信息系选修1号课程的学生视图(学号,姓名,成绩)
CREATE VIEW IS_S1(Sno,Sname,Grade)
AS
SELECT Student.Sno,Sname,Grade
FROM Student, SC
WHERE Sdept='IS' AND Student.Sno=SC.Sno AND SC.Cno='1';-- 建立信息系选修1号课程且成绩在90以上的学生视图
CREATE VIEW IS_S2(Sno,Sname,Grade)
AS
SELECT Sno,Sname,Grade
FROM IS_S1
WHERE Grade>=90;-- 定义一个反映学生出生年份的视图
CREATE VIEW BT_S(Sno,Sname,Sbirth)
AS
SELECT Sno,Sname,2025-Sage
FROM Student-- 将学生学号,平均成绩定义为一个视图
CREATE VIEW S_G(Sno,Gavg)
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;

8.2 删除视图

-- 如果在视图IS_S1上建立了视图IS_S2,需要先删除IS_S2
DROP VIEW IS_S2;-- 或
DROP VIEW IS_S1 CASCADE;

8.3 查询和更新视图

  • 视图定义后,对视图进行查询和更新的语句和语法与基本表相同;
  • 视图的查询与更新最终都会转换为对基本表的查询和更新,这一过程也被称为视图消解;
  • 一般来说,行列子集视图的查询和更新都可以顺利转换,其他则不一定;
SELECT Sno,Sage
FROM Student
WHERE Sdept='IS' AND Sage<20;-- 利用视图
SELECT Sno,Sage
FROM IS_Student
WHERE Sage<20;
http://www.dtcms.com/a/609376.html

相关文章:

  • 单页网站seo怎么做秦皇岛高端网站设计
  • 做网商必备网站手机百度关键词优化
  • python实现电脑手势识别截图
  • openEuler 全场景操作系统下 cpolar 内网穿透的价值深挖与协同优化
  • 为什么选择威洛博直线模组——从 3C、新能源、半导体到医疗的大致解析
  • 利用ArcPy批量检查管线隐患点与周边设施距离的实现方案
  • 【ZeroRange WebRTC】Amazon Kinesis Video Streams WebRTC SDK 音视频传输技术分析
  • 政务机关数字化办公核心系统
  • 盐城做网站企业新增网站推广教程
  • 衡东建设局网站公司内部交流 网站模板
  • 自己做网站要买什么在网站制作前需要有哪些前期策划工作
  • RAG系统学习之——RAG技术详解与实战指南
  • ASC学习笔记0014:手动添加一个新的属性集
  • 通过手机远程操控电脑,一步步学习便捷方法
  • 【AI学习-comfyUI学习-Segment Anything分割+实时图像裁剪-各个部分学习-第九节2】
  • [Linux]学习笔记系列 -- [kernel[params
  • AI 多模态全栈应用项目描述
  • SpringMVC(2)学习
  • 面向智能教育的生成式AI个性化学习内容生成研究
  • C语言编程代码编译 | 学习如何高效编译和调试C语言程序
  • 多模态学习与多模态模型
  • 网站建设费的税率网页设计制作用什么软件
  • Flutter Material 3设计语言详解
  • 天猫魔盒M19_晶晨S912H当贝桌面线刷机包_adb开启
  • 长沙seo优化排名东营优化网站
  • Python 编程实战 · 实用工具与库 — Flask 基础入门
  • supOS工厂操作系统 | 像“拼乐高”一样做数据分析
  • 青岛营销型网站推广wordpress doc导入
  • upload-labs(1-13)(配合源码分析)
  • Kubernetes-架构安装