文章目录
- SQL (Structured Query Language) \textbf{SQL (Structured Query Language)} SQL (Structured Query Language)
- 1. Relational Algebra \textbf{1. Relational Algebra} 1. Relational Algebra
- 1.0. Overview \textbf{1.0. Overview} 1.0. Overview
- 1.1. Projection ( π ) & Selection ( σ ) \textbf{1.1. Projection}(\pi{})\textbf{ \& Selection}(\sigma{}) 1.1. Projection(π) & Selection(σ)
- 1.2. Union/Set-Difference/Intersection \textbf{1.2. Union/Set-Difference/Intersection} 1.2. Union/Set-Difference/Intersection
- 1.3. Cross product & Joins \textbf{1.3. Cross product \& Joins} 1.3. Cross product & Joins
- 1.3.1. Cross Product ( × ) \textbf{1.3.1. Cross Product}(×) 1.3.1. Cross Product(×)
- 1.3.2. Inner Join ( ⋈ ) : Conditional Cross-Product \textbf{1.3.2. Inner Join}(\bowtie): \textbf{Conditional Cross-Product} 1.3.2. Inner Join(⋈):Conditional Cross-Product
- 1.3.3. Outer Join : Include Every Record \textbf{1.3.3. Outer Join}: \textbf{Include Every Record} 1.3.3. Outer Join:Include Every Record
- 1.3.4. \textbf{1.3.4. } 1.3.4. 复合 Join \textbf{Join} Join
- 2. SQL Overview \textbf{2. SQL Overview} 2. SQL Overview
- 2.1. CRUD Commends \textbf{2.1. CRUD Commends} 2.1. CRUD Commends
- 2.1.1. DDL Commands: Set up DB \textbf{2.1.1. DDL Commands: Set up DB} 2.1.1. DDL Commands: Set up DB
- 2.1.2. DCL Commands: \textbf{2.1.2. DCL Commands:} 2.1.2. DCL Commands: 用户与权限
- 2.1.3. Other: Database Administration \textbf{2.1.3. Other: Database Administration} 2.1.3. Other: Database Administration
- 2.2. SQL \textbf{2.2. SQL} 2.2. SQL 语法特点(大小写问题)
- 3. SQL Core: DML Commands \textbf{3. SQL Core: DML Commands} 3. SQL Core: DML Commands
- 3.1. \textbf{3.1. } 3.1. 变更表中内容
- 3.1.1. Insert Data: \textbf{3.1.1. Insert Data:} 3.1.1. Insert Data: `Insert Into`
- 3.1.2. Changes Existing Data: \textbf{3.1.2. Changes Existing Data:} 3.1.2. Changes Existing Data: `UPDATESET` 结构
- 3.1.3. Deleting Existing Data: \textbf{3.1.3. Deleting Existing Data:} 3.1.3. Deleting Existing Data: `DELETE`
- 3.2. \textbf{3.2. } 3.2. 查询表中内容: `SELECT FROM + XXX`
- 3.3. \textbf{3.3. } 3.3. 查询表中内容: Sub/Nesting Query \textbf{Sub/Nesting Query} Sub/Nesting Query
- 3.4. \textbf{3.4. } 3.4. 其他 SQL \textbf{SQL} SQL子句
- 4. 补充 Data Type \textbf{4. }补充\textbf{Data Type} 4. 补充Data Type
更多 资料与 笔记
SQL (Structured Query Language) \textbf{SQL (Structured Query Language)} SQL (Structured Query Language)
1. Relational Algebra \textbf{1. Relational Algebra} 1. Relational Algebra
1.0. Overview \textbf{1.0. Overview} 1.0. Overview
1️⃣关系操作:包括五个 Basic Operation \text{Basic Operation} Basic Operation
Operations \textbf{Operations} Operations 符号 原关系 操作(得到新关系) Projection \text{Projection} Projection π \pi π 原关系 → 2. 去除重复行 1. 保留想要的列 ( 竖直过滤 ) \large\xrightarrow[2. 去除重复行]{1. 保留想要的列(竖直过滤)} 1.保留想要的列(竖直过滤)2.去除重复行 Selection \text{Selection} Selection σ \sigma σ 原关系 → 保留想要的行 ( 水平过滤 ) \large\xrightarrow[]{保留想要的行(水平过滤)} 保留想要的行(水平过滤) Union \text{Union} Union ∪ \cup ∪ 原关系 1 + 1+ 1+原关系 2 2 2 → 2. 去除重复项 1. 合并两表所有Tuple \large\xrightarrow[2. 去除重复项]{1. 合并两表所有\text{Tuple}} 1.合并两表所有Tuple2.去除重复项 Intersection \text{Intersection} Intersection ∩ \cap ∩ 原关系 1 + 1+ 1+原关系 2 2 2 → 2. 去除重复项 1. 提取两个表都出现的Tuple \large\xrightarrow[2. 去除重复项]{1. 提取两个表都出现的\text{Tuple}} 1.提取两个表都出现的Tuple2.去除重复项 Set-difference/Minus \text{Set-difference/Minus} Set-difference/Minus − - − 原关系 1 + 1+ 1+原关系 2 2 2 → 移除关系 2 所含Tuple ( 在关系 1 中 ) \large\xrightarrow[]{移除关系2所含\text{Tuple}(在关系1中)} 移除关系2所含Tuple(在关系1中) Cross-product \text{Cross-product} Cross-product × × × 原关系 1 + 1+ 1+原关系 2 2 2 → Tuple无条件互相组合 ( 笛卡尔积 ) \large\xrightarrow[]{\text{Tuple}无条件互相组合(笛卡尔积)} Tuple无条件互相组合(笛卡尔积) Join \text{Join} Join ⋈ \bowtie ⋈ 原关系 1 + 1+ 1+原关系 2 2 2 → 2. 按条件Selection 1. Tuple无条件互相组合 \large\xrightarrow[2. 按条件\text{Selection}]{1.\text{Tuple}无条件互相组合} 1.Tuple无条件互相组合2.按条件Selection 2️⃣ Condition Expressions: \text{Condition Expressions:} Condition Expressions:
类型 符号 Arithmetic Expressions \text{Arithmetic Expressions} Arithmetic Expressions >, <, >=, <=, =, !=
AND/OR Clauses \text{AND/OR Clauses} AND/OR Clauses AND → Λ, OR → V
- 示例: σ rating ≥ 9 ∧ age<50 ( S 2 ) \sigma_{\text{rating}\geq{}9\text{ }\land{}\text{ age<50}}(\text{S}_2) σrating≥9 ∧ age<50(S2)
SELECT * FROM S2 WHERE rating >= 9 AND age < 50;
- 注意事项
- SQL \text{SQL} SQL与 C++ \text{C++} C++等不同,等于就是 =/ \text{=/} =/不是 == \text{==} ==
- 不等于的两种表达:
!=
或者<>
1.1. Projection ( π ) & Selection ( σ ) \textbf{1.1. Projection}(\pi{})\textbf{ \& Selection}(\sigma{}) 1.1. Projection(π) & Selection(σ)
1️⃣ Projection ( π ) \text{Projection}(\pi{}) Projection(π)
- 操作:仅保留 Projection List \text{Projection List} Projection List中的列 → \to{} →去除重复的行
- 特点: Projection is a costly operation, DB won’t operate it by default. \text{Projection is a costly operation, DB won't operate it by default.} Projection is a costly operation, DB won’t operate it by default.
- 示例:注意 SQL \text{SQL} SQL中可控制投影后去不去出重复项,但 Relational Algebra \text{Relational Algebra} Relational Algebra里默认去除重复项
SELECT * FROM Student; -- 选中所有列(左表) SELECT age FROM Student; -- 选中年龄这一列,但是SQL操作中默认不去除重复项(中表) SELECT DISTINCT age FROM Student; -- 选中年龄这一列,删除重复项(右表)
2️⃣ Selection ( σ ) \text{Selection}(\sigma{}) Selection(σ)
- 操作:仅保留 Selection \text{Selection} Selection条件的行,并且不会有任何重复行
- 示例:在 SQL \text{SQL} SQL中体现在
WHERE
上SELECT * FROM Student WHERE Student.rating >= 9;
3️⃣ Projection ( π ) & Selection ( σ ) \text{Projection}(\pi{})\text{ \& Selection}(\sigma{}) Projection(π) & Selection(σ)
- 注意事项
- 一般先 Selection \text{Selection} Selection后 Projection \text{Projection} Projection的 ( π A ( σ B ) ) (\pi{_{\text{A}}}(\sigma{_{\text{B}}})) (πA(σB))结构,这是因为 Selection \text{Selection} Selection不会改变表格结构
- 如果一定要用先 Projection \text{Projection} Projection再 Selection \text{Selection} Selection的 ( σ A ( π B ) ) (\sigma{_{\text{A}}}(\pi{_{\text{B}}})) (σA(πB))结构,要确保 A ⊆ B \text{A}\subseteq\text{B} A⊆B
- 示例:在 SQL \text{SQL} SQL中体现在
WHERE
和SELECT
上SELECT sname, rating FROM Student WHERE Student.rating >= 9;
1.2. Union/Set-Difference/Intersection \textbf{1.2. Union/Set-Difference/Intersection} 1.2. Union/Set-Difference/Intersection
对应的 SQL \text{SQL} SQL操作叫做 Set Operations \text{Set Operations} Set Operations
0️⃣条件( Union-Compatible \text{Union-Compatible} Union-Compatible):
- 两表 Column \text{Column} Column数一致,相应的列的 Data Type \text{Data Type} Data Type相同
- 两表属性名不一定要相同, SQL \text{SQL} SQL默认取上表的名
- 该条件适用 Union/Set Difference/Intersection \text{Union/Set Difference/Intersection} Union/Set Difference/Intersection三者
1️⃣ Union: \text{Union:} Union:
- 操作:将两表上下拼接在一起,并在 Relational Algebra \text{Relational Algebra} Relational Algebra中默认消除重复项
- 特性:对称性( Symmetric \text{Symmetric} Symmetric)
- 示例:在 SQL \text{SQL} SQL代码中体现在
UNION
上(但不默认消除重复项)SELECT sid, sname, rating, age FROM S1 -- 此操作去除重复行 UNION SELECT sid, sname, rating, age FROM S2; SELECT sid, sname, rating, age FROM S1 -- 此操作保留重复行 UNION ALL SELECT sid, sname, rating, age FROM S2;
2️⃣ Set-Difference: \text{Set-Difference:} Set-Difference:
- 操作:从一个关系中,删除另一个关系中存在的 Tuple \text{Tuple} Tuple
- 特性:无对称性( Asymmetric \text{Asymmetric} Asymmetric)
- 示例: SQL \text{SQL} SQL中并没有直接的求差集子句,可以通过子查询变相实现
SELECT sid, sname, rating, age FROM S1 WHERE (sid, sname, rating, age) NOT IN ( SELECT sid, sname, rating, age FROM S2 );
3️⃣ Intersection: Compound Operator \text{Intersection: Compound Operator} Intersection: Compound Operator
- 操作:找出两个关系中共存的 Tuples \text{Tuples} Tuples,本质上是混合运算 R ∩ S ≡ R − ( R − S ) \text{R}\cap{}\text{S}\equiv\text{R}-(\text{R}-\text{S}) R∩S≡R−(R−S)
- 示例:注意操作有对称性;同样也需要用 SQL \text{SQL} SQL子查询变相实现
SELECT sid, sname, rating, age FROM S1 WHERE (sid, sname, rating, age) IN ( SELECT sid, sname, rating, age FROM S2 );
1.3. Cross product & Joins \textbf{1.3. Cross product \& Joins} 1.3. Cross product & Joins
SQL Inter Table Operations \text{SQL Inter Table Operations} SQL Inter Table Operations
1.3.1. Cross Product ( × ) \textbf{1.3.1. Cross Product}(×) 1.3.1. Cross Product(×)
1️⃣操作:
- 用一个表的每行,依次去扫描另一个表的每一行,输出组合
- 结果会保留所有的列(即使重名了,也不要紧)
2️⃣重命名 ρ \rho{} ρ:
- 合并后的属性名称可能一样,由此需要重命名
- 比如 ρ ( C ( 1 → sid1 , 5 → sid2 ) , R × S ) \rho{(\text{C}(1\to{\text{sid1}},5\to{\text{sid2}}),\text{R}×\text{S}}) ρ(C(1→sid1,5→sid2),R×S)
- 1 → sid1 1\to{\text{sid1}} 1→sid1的意思是:第一列改成 sid1 \text{sid1} sid1
3️⃣ SQL \text{SQL} SQL代码
SELECT * FROM R, S; -- Cross product between R, S
1.3.2. Inner Join ( ⋈ ) : Conditional Cross-Product \textbf{1.3.2. Inner Join}(\bowtie): \textbf{Conditional Cross-Product} 1.3.2. Inner Join(⋈):Conditional Cross-Product
1️⃣ Inner Join(AKA Condition Join): \text{Inner Join(AKA Condition Join):} Inner Join(AKA Condition Join): R ⋈ Condition S = σ Condition ( R×S ) \text{R}\bowtie{_{\text{Condition}}}\text{S} = \sigma_{\text{Condition}}(\text{R×S}) R⋈ConditionS=σCondition(R×S)
- R ⋈ (S.sid<R.sid) S \text{R}\bowtie_{\text{(S}\text{.sid<R}\text{.sid)}}\text{S} R⋈(S.sid<R.sid)S中,先计算 R × S \text{R}×\text{S} R×S
- 再筛选满足 (R.sid<S.sid) {\text{(R}\text{.sid<S}\text{.sid)}}\text{} (R.sid<S.sid)的行
- SQL: \text{SQL: } SQL: ⚠️⚠️⚠️当两表中有 Column \text{Column} Column名撞了,应该在 Column \text{Column} Column名前加上表名
SELECT * FROM R INNER JOIN S ON R.sid < S.sid;
2️⃣ Natural Join(AKA Join): \text{Natural Join(AKA Join):} Natural Join(AKA Join): 一种隐式的 Inner Join \text{Inner Join} Inner Join
- 原理/计算步骤
- 先计算 R × S \text{R}×\text{S} R×S,找到两组(一组一或多个)名字相同的 Column \text{Column} Column(此处为 sid \text{sid} sid)
- 筛选两同名列值相同的行,然后只保留其中一列。即为 R ⋈ S ≡ R ⋈ R.sid=S.sid S \text{R}\bowtie{}\text{S}\equiv\text{R}\bowtie{_{\text{R.sid=S.sid}}}\text{S} R⋈S≡R⋈R.sid=S.sidS
- 注意事项:多个 Column \text{Column} Column相同匹配时,
NATURAL JOIN
要多列相等
即为 R ⋈ S ≡ R ⋈ R.sid=S.sid ∧ R.bid=S.bid S \text{R}\bowtie{}\text{S}\equiv\text{R}\bowtie{_{\text{R.sid=S.sid }\land{}\text{ R.bid=S.bid}}}\text{S} R⋈S≡R⋈R.sid=S.sid ∧ R.bid=S.bidS- SQL: \text{SQL: } SQL: ⚠️⚠️⚠️没有 Column \text{Column} Column相同匹配时,
NATURAL JOIN
语句会被执行为 Cross Product \text{Cross Product} Cross ProductSELECT * FROM R NATURAL JOIN S
3️⃣ Equi Join: \text{Equi Join:} Equi Join: 一种 Inner Join \text{Inner Join} Inner Join的特殊情况,比如 R ⋈ (S 1 .sid=R 2 .sid) S \text{R}\bowtie_{\text{(S}_1\text{.sid=R}_2\text{.sid)}}\text{S} R⋈(S1.sid=R2.sid)S(条件是等式)
SELECT * FROM R INNER JOIN S ON R.sid = S.sid;
1.3.3. Outer Join : Include Every Record \textbf{1.3.3. Outer Join}: \textbf{Include Every Record} 1.3.3. Outer Join:Include Every Record
1️⃣概述
Outer Join \textbf{Outer Join} Outer Join 操作 Left Outer Join \text{Left Outer Join} Left Outer Join 保留左表中所有记录,右表中不匹配的用 NULL \text{NULL} NULL代替 Right Outer Join \text{Right Outer Join} Right Outer Join 保留右表中所有记录,左表中不匹配的用 NULL \text{NULL} NULL代替 Full Outer Join \text{Full Outer Join} Full Outer Join 保留左右两表中所有记录,两表中不匹配的用 NULL \text{NULL} NULL代替 2️⃣示意图: Left/Right/Full \text{Left/Right/Full} Left/Right/Full
3️⃣示例
客户表 CID \textbf{CID} CID 属性 1 \textbf{1} 1 属性 2 \textbf{2} 2 账户表 CID \textbf{CID} CID AID \textbf{AID} AID 属性 3 \textbf{3} 3 / \text{/} / 1 \text{1} 1 X1 \text{X1} X1 Y1 \text{Y1} Y1 / \text{/} / 1 \text{1} 1 1 \text{1} 1 Z1 \text{Z1} Z1 / \text{/} / 2 \text{2} 2 X2 \text{X2} X2 Y2 \text{Y2} Y2 / \text{/} / 1 \text{1} 1 2 \text{2} 2 Z2 \text{Z2} Z2 / \text{/} / 3 \text{3} 3 X3 \text{X3} X3 Y3 \text{Y3} Y3 / \text{/} / 2 \text{2} 2 3 \text{3} 3 Z3 \text{Z3} Z3 / \text{/} / / \text{/} / / \text{/} / / \text{/} / / \text{/} / 4 \text{4} 4 4 \text{4} 4 Z4 \text{Z4} Z4
- Left Outer Join: \text{Left Outer Join:} Left Outer Join:
Customer.CustomerID = 3
时有表无匹配,所以代之以 NULL \text{NULL} NULLSELECT * FROM Customer LEFT OUTER JOIN Account ON Customer.CustomerID = Account.CustomerID; -- 左外联,保留左表所有CustomerID
CID \textbf{CID} CID 属性 1 \textbf{1} 1 属性 2 \textbf{2} 2 AID \textbf{AID} AID 属性 3 \textbf{3} 3 1 \text{1} 1 X1 \text{X1} X1 Y1 \text{Y1} Y1 1 \text{1} 1 Z1 \text{Z1} Z1 1 \text{1} 1 X1 \text{X1} X1 Y1 \text{Y1} Y1 2 \text{2} 2 Z2 \text{Z2} Z2 2 \text{2} 2 X2 \text{X2} X2 Y2 \text{Y2} Y2 3 \text{3} 3 Z3 \text{Z3} Z3 3 \text{3} 3 X3 \text{X3} X3 Y3 \text{Y3} Y3 NULL \text{NULL} NULL NULL \text{NULL} NULL - Right Outer Join: \text{Right Outer Join:} Right Outer Join:
Account.CustomerID = 4
时有表无匹配,所以代之以 NULL \text{NULL} NULLSELECT * FROM Customer RIGHT OUTER JOIN Account ON Customer.CustomerID = Account.CustomerID; -- 右外联,保留右表所有CustomerID
CID \textbf{CID} CID 属性 1 \textbf{1} 1 属性 2 \textbf{2} 2 AID \textbf{AID} AID 属性 3 \textbf{3} 3 1 \text{1} 1 X1 \text{X1} X1 Y1 \text{Y1} Y1 1 \text{1} 1 Z1 \text{Z1} Z1 1 \text{1} 1 X1 \text{X1} X1 Y1 \text{Y1} Y1 2 \text{2} 2 Z2 \text{Z2} Z2 2 \text{2} 2 X2 \text{X2} X2 Y2 \text{Y2} Y2 3 \text{3} 3 Z3 \text{Z3} Z3 4 \text{4} 4 NULL \text{NULL} NULL NULL \text{NULL} NULL 4 \text{4} 4 Z4 \text{Z4} Z4 - Full Outer Join: \text{Full Outer Join:} Full Outer Join: 也可以认为是 Right Outer Join结果 ∪ Leftt Outer Join结果 \text{Right Outer Join结果}\cup\text{Leftt Outer Join结果} Right Outer Join结果∪Leftt Outer Join结果
SELECT * FROM Customer FULL OUTER JOIN Account ON Customer.CustomerID = Account.CustomerID; -- 全外联,保留两表所有CustomerID
CID \textbf{CID} CID 属性 1 \textbf{1} 1 属性 2 \textbf{2} 2 AID \textbf{AID} AID 属性 3 \textbf{3} 3 1 \text{1} 1 X1 \text{X1} X1 Y1 \text{Y1} Y1 1 \text{1} 1 Z1 \text{Z1} Z1 1 \text{1} 1 X1 \text{X1} X1 Y1 \text{Y1} Y1 2 \text{2} 2 Z2 \text{Z2} Z2 2 \text{2} 2 X2 \text{X2} X2 Y2 \text{Y2} Y2 3 \text{3} 3 Z3 \text{Z3} Z3 3 \text{3} 3 X3 \text{X3} X3 Y3 \text{Y3} Y3 NULL \text{NULL} NULL NULL \text{NULL} NULL 4 \text{4} 4 NULL \text{NULL} NULL NULL \text{NULL} NULL 4 \text{4} 4 Z4 \text{Z4} Z4 1.3.4. \textbf{1.3.4. } 1.3.4. 复合 Join \textbf{Join} Join
1️⃣示例的 ABC \text{ABC} ABC表格
A \small\textbf{A} A AID \small\textbf{AID} AID AName \small\textbf{AName} AName B \small\textbf{B} B BID \small\textbf{BID} BID AID \small\textbf{AID} AID BName \small\textbf{BName} BName C \small\textbf{C} C CID \small\textbf{CID} CID CType \small\textbf{CType} CType BName \small\textbf{BName} BName / \text{/} / 1 \text{1} 1 AName1
/ \text{/} / 101 \text{101} 101 1 \text{1} 1 BName1
/ \text{/} / 1001 \text{1001} 1001 CType1
BName2
/ \text{/} / 2 \text{2} 2 AName2
/ \text{/} / 102 \text{102} 102 1 \text{1} 1 BName2
/ \text{/} / 1002 \text{1002} 1002 CType2
BName3
/ \text{/} / / \text{/} / / \text{/} / / \text{/} / 201 \text{201} 201 2 \text{2} 2 BName3
/ \text{/} / / \text{/} / / \text{/} / / \text{/} / 2️⃣ Inner Join \text{Inner Join} Inner Join
A INNER JOIN B ON A.AID = B.AID
A.AID \textbf{A.AID} A.AID A.AName \textbf{A.AName} A.AName B.ID \textbf{B.ID} B.ID B.AID \textbf{B.AID} B.AID B.BName \textbf{B.BName} B.BName 1 \text{1} 1 AName1
101 \text{101} 101 1 \text{1} 1 BName1
1 \text{1} 1 AName1
102 \text{102} 102 1 \text{1} 1 BName2
2 \text{2} 2 AName2
201 \text{201} 201 2 \text{2} 2 BName3
2️⃣复合 Inner Join: \text{Inner Join:} Inner Join: 拿上面那个 Join \text{Join} Join的结果再去 Join \text{Join} Join
A INNER JOIN B ON A.AID = B.AID INNER JOIN C ON B.BName = C.BName
A.AID \small\textbf{A.AID} A.AID A.AName \small\textbf{A.AName} A.AName B.ID \small\textbf{B.ID} B.ID B.AID \small\textbf{B.AID} B.AID B.BName \small\textbf{B.BName} B.BName C.CID \small\textbf{C.CID} C.CID C.CType \small\textbf{C.CType} C.CType C.BName \small\textbf{C.BName} C.BName 1 \text{1} 1 AName1
101 \text{101} 101 1 \text{1} 1 BName2
1001 \text{1001} 1001 CType1
BName2
2 \text{2} 2 AName2
201 \text{201} 201 2 \text{2} 2 BName3
1002 \text{1002} 1002 CType2
BName3
2. SQL Overview \textbf{2. SQL Overview} 2. SQL Overview
2.1. CRUD Commends \textbf{2.1. CRUD Commends} 2.1. CRUD Commends
Create/Read/Update/Delete Commands \text{Create/Read/Update/Delete Commands} Create/Read/Update/Delete Commands
Command Type \textbf{Command Type} Command Type 功能 Description \textbf{Description} Description DDL \text{DDL} DDL Definition \text{Definition} Definition 定义并建立数据库 DML \text{DML} DML Manipulation \text{Manipulation} Manipulation 维护并使用(查询)数据库,获取数据的价值与信息 DCL \text{DCL} DCL Control \text{Control} Control 控制用户对数据的访问权 Other \text{Other} Other N/A \text{N/A} N/A 管理数据库 2.1.1. DDL Commands: Set up DB \textbf{2.1.1. DDL Commands: Set up DB} 2.1.1. DDL Commands: Set up DB
1️⃣创建表格操作
CREAT
,其实也就是 Implementation \text{Implementation} Implementation操作-- 创建Customer表 CREATE TABLE Customer ( CustomerID INT PRIMARY KEY, CustFirstName VARCHAR(45) ); -- 创建Account表 CREATE TABLE Account ( -- 若表中现有最后一行ID是1001,插入的新ID自动变成1002 AccountID INT AUTO_INCREMENT PRIMARY KEY, -- 枚举数据类型,只允许账户号码为三者之一 AccountNumber ENUM('Num1', 'Num2', 'Num3'); Customer_CustomerID INT, FOREIGN KEY (Customer_CustomerID) REFERENCES Customer(CustomerID) );
- 关于 Key \text{Key} Key
- 要用
PRIMARY KEY
指定哪个变量时主键- 要用
FOREIGN KEY REFERENCES
指定 Foreign Key \text{Foreign Key} Foreign Key引用的哪个变量,否则会 Syntax Error \text{Syntax Error} Syntax Error- 补充事项
AUTO_INCREMENT
: 用来标记主键字段,插入一个记录后被标记字段自动 +1 \text{+1} +1ENUM
: 枚举数据类型类型,只允许属性为预设值2️⃣修改表格系列操作
操作 关键字 增加表格的 Attributes \text{Attributes} Attributes ALTER TABLE <表名> ADD <属性名> <属性类型>
减少表格的 Attributes \text{Attributes} Attributes ALTER TABLE <表名> DROP <属性名>
表格重命名 RENAME TABLE <旧表名> TO <新表名>
快速清空表格记录( Can’t Roll Back \text{Can't Roll Back} Can’t Roll Back) TRUNCATE TABLE <表名>
慢速清空表格记录( Can Roll Back \text{Can Roll Back} Can Roll Back) DELETE * FROM <表名>
彻底删除(杀死)一个表格 DROP * FROM <表名>
-- 添加属性: 客户表中添加CustLastName属性 ALTER TABLE Customer ADD CustLastName VARCHAR(45); -- 减少属性: 账户表中删除AccountNumber属性 ALTER TABLE Account DROP AccountNumber; -- 重命名: 将Customer表重命名为NewCustomers RENAME TABLE Customer TO NewCustomers -- 快速清空表记录: 清空所有客户的数据,不回退 TRUNCATE TABLE Customer -- 慢速清空表记录: 清空所有客户的数据,可回退 DELETE * FROM Customer -- 彻底删除表格: 把客户表的数据/客户表都根除 DROP TABLE Customer
3️⃣查看表格操作:
VIEW
视图,只是一种虚拟表(不存储在内存中)-- 创建虚拟表格CustomerAccountView视图 CREATE VIEW CustomerAccountView AS SELECT Customer.CustomerID, Account.AccountNumber FROM Customer JOIN Account ON Customer.CustomerID = Account.Customer_CustomerID; -- 通过视图来查询数据,就像查询普通表格一样,简化了查询 SELECT * FROM CustomerAccountView;
2.1.2. DCL Commands: \textbf{2.1.2. DCL Commands:} 2.1.2. DCL Commands: 用户与权限
1️⃣创建/删除用户:
CREATE USER/DROP USER
-- 创建用户,初始密码为123 CREATE USER 'john'@'localhost' IDENTIFIED BY '123'; -- 删除john用户 DROP USER 'john'@'localhost';
2️⃣分配/撤销用户权限:
GRANT / REVOKE
-- 授予john在mydatabase数据库Table1表的SELECT和INSERT权限 GRANT SELECT,INSERT ON mydatabase.Table1 TO 'john'@'localhost'; -- 撤销john在mydatabase数据库Table1表的INSERT权限 REVOKE INSERT ON mydatabase.Table1 FROM 'john'@'localhost';
3️⃣设置密码:
SET PASSWORD
-- 设置新密码为0123 SET PASSWORD FOR 'john'@'localhost' = PASSWORD('0123');
2.1.3. Other: Database Administration \textbf{2.1.3. Other: Database Administration} 2.1.3. Other: Database Administration
1️⃣意外删除的恢复:
BACKUP TABLE/RESTORE TABLE
(二者其实并非标准 SQL \text{SQL} SQL命令)2️⃣展示表格模式( Scheme \text{Scheme} Scheme):
DESCRIBE <表名>
CREATE TABLE Customer ( CustomerID INT AUTO_INCREMENT PRIMARY KEY, CustFirstName VARCHAR(45), DateOfBirth DATE ); -- 查看Customer表的结构,结果如下表 DESCRIBE Customer
Field \textbf{Field} Field Type \textbf{Type} Type Null \textbf{Null} Null Key \textbf{Key} Key Default \textbf{Default} Default Extra \textbf{Extra} Extra CustomerID \text{CustomerID} CustomerID INT \text{INT} INT NO \text{NO} NO PRI \text{PRI} PRI NULL \text{NULL} NULL auto_increment \text{auto\_increment} auto_increment CustFirstName \text{CustFirstName} CustFirstName VARCHAR(45) \text{VARCHAR(45)} VARCHAR(45) YES \text{YES} YES NULL \text{NULL} NULL DateOfBirth \text{DateOfBirth} DateOfBirth DATE \text{DATE} DATE YES \text{YES} YES NULL \text{NULL} NULL 3️⃣
USE <db_name>
: 挑选进入哪个数据库来操作2.2. SQL \textbf{2.2. SQL} 2.2. SQL 语法特点(大小写问题)
1️⃣ SQL \text{SQL} SQL的属性名大小/关键词写不敏感( Case Inseneitive \text{Case Inseneitive} Case Inseneitive),但一般大写。如下两段查询含义相同
SELECT * FROM Furniture WHERE (Type = 'Chair' AND Colour = 'Black') OR (Type = 'Lamp' AND Colour = 'Black'); select * from furniture where (type = 'Chair' and colour = 'Black') or (type = 'Lamp' and colour = 'Black');
3️⃣ SQL \text{SQL} SQL的表名区分大小写
3. SQL Core: DML Commands \textbf{3. SQL Core: DML Commands} 3. SQL Core: DML Commands
3.1. \textbf{3.1. } 3.1. 变更表中内容
3.1.1. Insert Data: \textbf{3.1.1. Insert Data:} 3.1.1. Insert Data:
Insert Into
0️⃣示例表格
CustID \textbf{CustID} CustID FirstName \textbf{FirstName} FirstName MiddleName \textbf{MiddleName} MiddleName LastName \textbf{LastName} LastName BusinessName \textbf{BusinessName} BusinessName CustType \textbf{CustType} CustType 1 \text{1} 1 Peter \text{Peter} Peter NULL \text{NULL} NULL Smith \text{Smith} Smith NULL \text{NULL} NULL Personal \text{Personal} Personal 2 \text{2} 2 James \text{James} James NULL \text{NULL} NULL Jones \text{Jones} Jones JJ \text{JJ} JJ Company \text{Company} Company 3 \text{3} 3 NULL \text{NULL} NULL NULL \text{NULL} NULL Smythe \text{Smythe} Smythe NULL \text{NULL} NULL Company \text{Company} Company 1️⃣显式插入:指名要给哪几个属性插入数据
-- 一次性可以插入一条数据 INSERT INTO Customer (FirstName, LastName, CustType) VALUES ("Peter", "Smith", 'Personal'); -- 也可以多条 INSERT INTO Customer (FirstName, LastName, CustType) VALUES ("Peter" , "Smith" , 'Personal'), ("Jamnes", "Jones" , 'Company' ), ("" , "Smythe", 'Company' );
2️⃣隐式插入:省略具体的属性,将提供的值按顺序依次插入属性
-- 插入第一条数据,DEFAULT子句会让CustID从0开始自动+1(此处+1后CustID=1) INSERT INTO Customer VALUES (DEFAULT, "Peter", "", "Smith", "", 'Personal'); -- 一次性插入多条数据 INSERT INTO Customer VALUES (DEFAULT, "Peter", "" , "Smith" , "" , 'Personal'); (DEFAULT, "James", NULL, "Jones" , "JJ", 'Company' ); (DEFAULT, "" , NULL, "Smythe", "" , 'Company' );
3️⃣从其他表格插入数据
-- 将所有Customer中的记录,全部插入NewCustomer中 INSERT INTO NewCustomer SELECT * FROM Customer;
👽
REPLACE
和INSERT
功能几乎一致,区别仅仅在于,当待插入记录的 PK ↔ 冲突 相同 \text{PK}\xleftrightarrow[冲突]{相同} PK相同 冲突已存在记录的 PK \text{PK} PK
INSERT
:操作费费,插入失败REPLACE
:操作合法,并且待插入记录覆盖冲突的已存在记录3.1.2. Changes Existing Data: \textbf{3.1.2. Changes Existing Data:} 3.1.2. Changes Existing Data:
UPDATESET
结构1️⃣
UPDATE
示例-- Block1: 所有薪水小于100000的涨薪5% UPDATE Salaried SET AnnualSalary = AnnualSalary * 1.05 WHERE AnnualSalary <= 100000; -- Block2: 所有薪水大于100000的涨薪10% UPDATE Salaried SET AnnualSalary = AnnualSalary * 1.10 WHERE AnnualSalary > 100000;
- 子句执行的顺序会影响结果
- 没有
WHERE
子句时,更新会应用到表格的每一行2️⃣
CASE
Command \text{Command} Command优化示例UPDATE Salaried SET AnnualSalary = CASE WHEN AnnualSalary <= 100000 THEN AnnualSalary * 1.05 ELSE AnnualSalary * 1.10 END;
3.1.3. Deleting Existing Data: \textbf{3.1.3. Deleting Existing Data:} 3.1.3. Deleting Existing Data:
DELETE
1️⃣简答例子
-- 删除表中所有记录,危险操作 DELETE FROM Employee -- 删除表中满足条件的操作 DELETE FROM Employee WHERE Name = "Grace"
2️⃣删除的外键约束
约束子句 尝试操作 执行操作 ON DELETE CASCADE
A \text{A} A表尝试删除一行 操作总被允许,引用该行的 B \text{B} B表行都删除 ON DELETE RESTRICT
A \text{A} A表尝试删除一行 如果改行被 B \text{B} B表引用,则删除操作被禁止 CREATE TABLE B ( Bid INT PRIMARY KEY, Bname VARCHAR(50), Aid INT, FOREIGN KEY (Aid) REFERENCES A(Aid) ON DELETE CASCADE FOREIGN KEY (Aid) REFERENCES A(Aid) ON DELETE RESTRICT -- 二选一 );
3.2. \textbf{3.2. } 3.2. 查询表中内容:
SELECT FROM + XXX
3.2.1. \textbf{3.2.1. } 3.2.1.
SELECT
有关结构1️⃣最基本结构:
- 投影,原理详见关系代数
SELECT * FROM Student; -- 选中所有列, Heap Scan SELECT age FROM Student; -- 选中年龄这一列,但是SQL操作中默认不去除重复项
- 关于
DISTINCT
,其后所有属性都要删除重复项SELECT DISTINCT age FROM Student; -- 选中年龄这一列,删除重复项 SELECT DISTINCT age,name FROM Student; -- 年龄+姓名的组合要DISTINCT,删除重复项
2️⃣聚合函数 Aggregare Function \text{Aggregare Function} Aggregare Function
- 概述
Function \textbf{Function} Function Description \textbf{Description} Description AVG()
Average Value \text{Average Value} Average Value MIN()
Minimum Value \text{Minimum Value} Minimum Value MAX()
Maximum Value \text{Maximum Value} Maximum Value COUNT()
Number of Values \text{Number of Values} Number of Values(行数) SUM()
Sum of Values \text{Sum of Values} Sum of Values - 示例
CustomerID \textbf{CustomerID} CustomerID AccountID \textbf{AccountID} AccountID Balance \textbf{Balance} Balance 1 \text{1} 1 1 \text{1} 1 200 \text{200} 200 1 \text{1} 1 2 \text{2} 2 100 \text{100} 100 2 \text{2} 2 1 \text{1} 1 400 \text{400} 400 3 \text{3} 3 1 \text{1} 1 300 \text{300} 300
COUNT
示例SELECT COUNT(*) FROM Customer; -- 表中有多少Tuples SELECT COUNT(CustomerID) FROM Customer; -- 多少个CustomerID SELECT COUNT(DISTINCT CustomerID) FROM Customer; -- 多少个Uniqe的ID
COUNT(CustomerID) \textbf{COUNT(CustomerID)} COUNT(CustomerID) \ COUNT(DISTINCT CustomerID) \textbf{COUNT(DISTINCT CustomerID)} COUNT(DISTINCT CustomerID) 4 \text{4} 4 \ 3 \text{3} 3 AVG/MAX/MAX
示例SELECT AVG(Balance) FROM Account; -- 所有账户余额的平均 SELECT MAX(Balance) FROM Account WHERE CustomerID=1; -- 用户1最高账户余额 SELECT SUM(Balance) FROM Account GROUP BY CustomerID; -- 各用户账户总余额
AVG(Balance) \textbf{AVG(Balance)} AVG(Balance) / \text{/} / MAX(Balance) \textbf{MAX(Balance)} MAX(Balance) / \text{/} / SUM(Balance) \textbf{SUM(Balance)} SUM(Balance) 250 \text{250} 250 / \text{/} / 200 \text{200} 200 / \text{/} / 300 \text{300} 300 / \text{/} / / \text{/} / / \text{/} / / \text{/} / 400 \text{400} 400 / \text{/} / / \text{/} / / \text{/} / / \text{/} / 300 \text{300} 300 SUM()
补充:
- 当用于数值类型属性时,会遍历每行求出并返回总和
- 当用于布尔类型属性时,会遍历每行(布尔真 =1/ \text{=1/} =1/布尔假 =0 \text{=0} =0),返回总和
3️⃣重命名子句
AS
Clause \text{Clause} ClauseSELECT CustType, COUNT(CustomerID) FROM Customer -- 不重命名 SELECT CustType, COUNT(CustomerID) AS Count FROM Customer -- 重命名为Count
不重命名 CustType \textbf{CustType} CustType Count(CustomerID) \textbf{Count(CustomerID)} Count(CustomerID) 重命名 CustType \textbf{CustType} CustType Count \textbf{Count} Count / \text{/} / Type1 \text{Type1} Type1 3 \text{3} 3 / \text{/} / Type1 \text{Type1} Type1 3 \text{3} 3 / \text{/} / Type2 \text{Type2} Type2 6 \text{6} 6 / \text{/} / Type2 \text{Type2} Type2 6 \text{6} 6 4️⃣合并列子句
CONCAT
: 将两个不同的列,合并为一列SELECT CONCAT(FirstName, LastName) AS FullName FROM Name
3.2.2. \textbf{3.2.2. } 3.2.2.
FROM
有关结构1️⃣最基本功能:选定要操作的表格
SELECT * FROM R
2️⃣跨表格操作: Cross-Product/Join \text{Cross-Product/Join} Cross-Product/Join,原理详见关系代数部分
- Cross-Product \text{Cross-Product} Cross-Product
SELECT * FROM R, S; -- Cross product between R, S
- Join \text{Join} Join
SELECT * FROM R NATURAL JOIN S -- Nature Join SELECT * FROM R INNER JOIN S ON R.sid < S.sid; -- Inner Join SELECT * FROM R INNER JOIN S ON R.sid = S.sid; -- Equi Join SELECT * FROM R LEFT OUTER JOIN S ON R.sid = S.sid; -- Left Outer Join SELECT * FROM R RIGHT OUTER JOIN S ON R.sid = S.sid; -- Right Outer Join SELECT * FROM R FULL OUTER JOIN S ON R.sid = S.sid; -- Full Outer Join
3.2.3. \textbf{3.2.3. } 3.2.3.
+XXX
有关结构3.2.3.1. \textbf{3.2.3.1. } 3.2.3.1.
WHERE
有关结构1️⃣
WHERE
Clause: \text{Clause:} Clause: 本是上是一种 Selection \text{Selection} Selection操作,过滤满足条件SELECT * FROM Student WHERE Student.rating >= 9;
2️⃣
LIKE
Clause: \text{Clause:} Clause: 与WHERE
配合使用,实现字符串的匹配==(约等于)==
- 匹配的关键字
1 \textbf{1} 1个不确定的字符 0-M \textbf{0-M} 0-M个不确定的字符 _ \text{\_} _ % \text{\%} % - 匹配子句示例
Clause \textbf{Clause} Clause CustomerName
Maches \textbf{Maches} Maches示例 WHERE CustomerName LIKE 'a%'
以 a \text{a} a开始的 axxxxx
WHERE CustomerName LIKE '%a'
以 a \text{a} a结束的 xxxxxa
WHERE CustomerName LIKE '%a%'
包含 a \text{a} a的 xxaxxx
WHERE CustomerName LIKE '_a%'
a \text{a} a在第二位的 xaxxxx
WHERE CustomerName LIKE 'a_%_%'
以 a \text{a} a开始,后至少两字符 axx/axxx
WHERE CustomerName LIKE 'a%o'
以 a \text{a} a开始 o \text{o} o结尾 axxxxo
- SQL \text{SQL} SQL示例
SELECT CustLastName FROM Customer WHERE CustLastName LIKE "Sm%" -- 匹配的会有Smith/Smyth/Smize......
3.2.3.2. \textbf{3.2.3.2. } 3.2.3.2.
GROUP BY
有关结构1️⃣
GROUP BY
Clause: \text{Clause:} Clause:
- 讲记录根据一个/多个属性,分为若干小组
- 通常和聚合函数结合使用,为每个小组计算出独立结果
- 示例
SELECT CustID, AVG(Balance) AS AveBalance FROM Account GROUP BY CustID;
CustID \textbf{CustID} CustID Account \textbf{Account} Account Balance \textbf{Balance} Balance → 查询 结果 \xrightarrow[查询]{结果} 结果查询 CustID \textbf{CustID} CustID AveBalance \textbf{AveBalance} AveBalance 1 \text{1} 1 101 \text{101} 101 500 \text{500} 500 / \text{/} / 1 \text{1} 1 325 \text{325} 325 1 \text{1} 1 102 \text{102} 102 150 \text{150} 150 / \text{/} / 2 \text{2} 2 250 \text{250} 250 2 \text{2} 2 103 \text{103} 103 200 \text{200} 200 / \text{/} / 3 \text{3} 3 450 \text{450} 450 2 \text{2} 2 104 \text{104} 104 300 \text{300} 300 / \text{/} / / \text{/} / / \text{/} / 3 \text{3} 3 105 \text{105} 105 450 \text{450} 450 / \text{/} / / \text{/} / / \text{/} / - 复杂一些的例子:
GROUP BY <复合属性>
SELECT Subject, Semester, COUNT(*) FROM Example_Table GROUP BY Subject, Semester; -- Subject, Semester都相同才能分为一类
Subject \small\textbf{Subject} Subject Semester \small\textbf{Semester} Semester Attendee \small\textbf{Attendee} Attendee → 查询 结果 \xrightarrow[查询]{结果} 结果查询 Subject \small\textbf{Subject} Subject Semester \small\textbf{Semester} Semester COUNT(*) \small\textbf{COUNT(*)} COUNT(*) ITB001 \small\text{ITB001} ITB001 1 \text{1} 1 John \small\text{John} John / \text{/} / ITB001 \small\text{ITB001} ITB001 1 \text{1} 1 3 \text{3} 3 ITB001 \small\text{ITB001} ITB001 1 \text{1} 1 Bob \small\text{Bob} Bob / \text{/} / ITB001 \small\text{ITB001} ITB001 2 \text{2} 2 2 \text{2} 2 ITB001 \small\text{ITB001} ITB001 1 \text{1} 1 Mickey \small\text{Mickey} Mickey / \text{/} / IMK114 \small\text{IMK114} IMK114 1 \text{1} 1 2 \text{2} 2 ITB001 \small\text{ITB001} ITB001 2 \text{2} 2 Jenny \small\text{Jenny} Jenny / \text{/} / / \text{/} / / \text{/} / / \text{/} / ITB001 \small\text{ITB001} ITB001 2 \text{2} 2 James \small\text{James} James / \text{/} / / \text{/} / / \text{/} / / \text{/} / IMK114 \small\text{IMK114} IMK114 1 \text{1} 1 John \small\text{John} John / \text{/} / / \text{/} / / \text{/} / / \text{/} / IMK114 \small\text{IMK114} IMK114 1 \text{1} 1 Erica \small\text{Erica} Erica / \text{/} / / \text{/} / / \text{/} / / \text{/} / 2️⃣
HAVING
Clause: \text{Clause:} Clause: 适用于GROUP BY
体质的WHERE
,只能和GROUP BY
一起出现
- 作用:作为聚合函数的补充,用于筛选
GROUP BY
出来的组- 对比:
HAVING
Clause \textbf{Clause} ClauseWHERE
Clause \textbf{Clause} Clause后接关系 Attribute \text{Attribute} Attribute有关条件 后接聚合函数(数结)果有关条件 - 示例:注意区分
WHERE
和HAVING
CustID \textbf{CustID} CustID Account \textbf{Account} Account Balance \textbf{Balance} Balance 1 \text{1} 1 101 \text{101} 101 500 \text{500} 500 1 \text{1} 1 102 \text{102} 102 150 \text{150} 150 2 \text{2} 2 103 \text{103} 103 200 \text{200} 200 2 \text{2} 2 104 \text{104} 104 300 \text{300} 300 3 \text{3} 3 105 \text{105} 105 450 \text{450} 450
WHERE <条件表达式>
:直接过滤原始的数据(过滤数据)SELECT CustID, Balance FROM Customer WHERE Balance > 400;
HAVING <条件表达式>
:对分组的结果进行过滤(过滤组)
查询 CustID \small\textbf{CustID} CustID AveBalance \small\textbf{AveBalance} AveBalance HAVING
后CustID \small\textbf{CustID} CustID AveBalance \small\textbf{AveBalance} AveBalance / \text{/} / 1 \text{1} 1 325 \text{325} 325 / \text{/} / 1 \text{1} 1 325 \text{325} 325 / \text{/} / 2 \text{2} 2 250 \text{250} 250 / \text{/} / 3 \text{3} 3 450 \text{450} 450 / \text{/} / 3 \text{3} 3 450 \text{450} 450 / \text{/} / / \text{/} / / \text{/} / SELECT CustID, AVG(Balance) AS AveBalance FROM Account GROUP BY CustID HAVING AveBalance > 300;
3.2.3.3. \textbf{3.2.3.3. } 3.2.3.3.
ORDER BY
有关结构1️⃣
ORDER BY
Clause: \text{Clause:} Clause:
- 将查询得到的结果按照某一属性排序
SELECT Name, Type FROM Customer ORDER BY Name; -- 按名字(字典序)默认升序 SELECT Name, Type FROM Customer ORDER BY Name ASC; -- 升序 SELECT Name, Type FROM Customer ORDER BY Name DESC; -- 降序
- 将查询得到的结果按照符合属性排序
SELECT Name, Type FROM Customer ORDER BY Name DESC, Type ASC; -- 先按Name降序排序 -- 再对于Name相同的Tuple,按照Type升序排序
2️⃣
LIMIT/OFFSET
Clause: \text{Clause:} Clause:
- 含义
Clause \textbf{Clause} Clause 功能 LIMIT N
选取排序结果的前 N \text{N} N个 OFFSET M
跳过 M \text{M} M个排序结果 LIMIT N OFFSET M
跳过排序结果的前 M \text{M} M个,依次选取后面的 N \text{N} N个 - 示例:
SELECT Name, Type FROM Customer ORDER BY Name LIMIT 5; -- 红色 SELECT Name, Type FROM Customer ORDER BY Name LIMIT 5 OFFSET 3; -- 绿色
3.3. \textbf{3.3. } 3.3. 查询表中内容: Sub/Nesting Query \textbf{Sub/Nesting Query} Sub/Nesting Query
3.3.1. Subquery \textbf{3.3.1. Subquery} 3.3.1. Subquery结构
0️⃣概述
SELECT
结构相当于一个查询,在一个SELECT
中插入另一个SELECT
,则后者就是前者子查询- 执行顺序:先执行子查询 → \to{} →将子查询结果传给主查询 → \to{} →执行主查询
- 相关子查询:子查询可以直接使用主(外层)查询的列/值
1️⃣在
SELECT
字句中插入子查询,一般使用AS
重命名子查询返回的列SELECT name, (SELECT COUNT(*) FROM orders) AS order_count FROM customers;
2️⃣在
FROM
字句中插入子查询,子查询此时相当于一个临时表,所以必须使用AS
重命名SELECT tmp.average_sales FROM (SELECT AVG(amount) AS average_sales FROM sales) AS tmp;
3️⃣在
WHERE
子句中SELECT name, age FROM employees WHERE salary > (SELECT AVG(salary) FROM employees);
4️⃣在
EXISTS
中,返回布尔值的特殊类子查询SELECT name FROM products WHERE EXISTS (SELECT 1 FROM inventory WHERE inventory.quantity > 0);
3.3.2. Subquery \textbf{3.3.2. Subquery} 3.3.2. Subquery有关子句
0️⃣示例表格
- Artefact/Seller/Buyer \text{Artefact/Seller/Buyer} Artefact/Seller/Buyer表
AID \small\textbf{AID} AID Name \small\textbf{Name} Name 描述 描述 描述 \small\text{\\} SID \small\textbf{SID} SID Name \small\text{Name} Name Phone \small\textbf{Phone} Phone \small\text{\\} BID \small\textbf{BID} BID Name \small\textbf{Name} Name 电话 电话 电话 1 \small\text{1} 1 Vase \small\text{Vase} Vase Old \small\text{Old} Old \small\text{\\} 1 \small\text{1} 1 Abby \small\text{Abby} Abby 0232 \small\text{0232} 0232 \small\text{\\} 1 \small\text{1} 1 Magg \small\text{Magg} Magg 0333 \small\text{0333} 0333 2 \small\text{2} 2 Knife \small\text{Knife} Knife Old \small\text{Old} Old \small\text{\\} 2 \small\text{2} 2 Ben \small\text{Ben} Ben 0311 \small\text{0311} 0311 \small\text{\\} 2 \small\text{2} 2 Nicole \small\text{Nicole} Nicole 0444 \small\text{0444} 0444 3 \small\text{3} 3 Pot \small\text{Pot} Pot Old \small\text{Old} Old \small\text{\\} 3 \small\text{3} 3 Carl \small\text{Carl} Carl 0333 \small\text{0333} 0333 \small\text{\\} 3 \small\text{3} 3 Oleg \small\text{Oleg} Oleg 0555 \small\text{0555} 0555 - Offer \text{Offer} Offer表
AID \small\textbf{AID} AID SID \small\textbf{SID} SID BID \small\textbf{BID} BID Date \small\textbf{Date} Date Amount \small\textbf{Amount} Amount Acceptance \small\textbf{Acceptance} Acceptance 1 \small\text{1} 1 1 \small\text{1} 1 1 \small\text{1} 1 2012-06-20 \small\text{2012-06-20} 2012-06-20 81223.23 \small\text{81223.23} 81223.23 N \small\text{N} N 1 \small\text{1} 1 1 \small\text{1} 1 2 \small\text{2} 2 2012-06-20 \small\text{2012-06-20} 2012-06-20 82223.23 \small\text{82223.23} 82223.23 N \small\text{N} N 1 \small\text{1} 1 2 \small\text{2} 2 1 \small\text{1} 1 2012-06-20 \small\text{2012-06-20} 2012-06-20 19.95 \small\text{19.95} 19.95 N \small\text{N} N 2 \small\text{2} 2 2 \small\text{2} 2 2 \small\text{2} 2 2012-06-20 \small\text{2012-06-20} 2012-06-20 23.00 \small\text{23.00} 23.00 N \small\text{N} N 1️⃣
IN/NOT IN
Clause: \text{Clause:} Clause: 记录是否在子查询的结果中SELECT * FROM Buyer WHERE BID IN (SELECT BID FROM Offer WHERE AID = 1)
- 子查询结果:
BuyerID = 1/2
,主查询结果
BID \textbf{BID} BID Name \textbf{Name} Name Phone \textbf{Phone} Phone 1 \text{1} 1 Magg \text{Magg} Magg 0333 \text{0333} 0333 2 \text{2} 2 Nicole \text{Nicole} Nicole 0444 \text{0444} 0444 - 基于 Join \text{Join} Join的优化:执行的效率会更高
ELECT Buyer.* FROM Buyer JOIN Offer ON Buyer.BID = Offer.BID WHERE Offer.AID = 1;
2️⃣
ANY/ALL/EXISTS
ANY
:满足至少一个内部条件,实际上可以把所有的IN
改为=ANY
(至少一个等于)SELECT empno, sal FROM emp WHERE sal > ANY (SELECT....返回:Tuple1, Tuple2, Tuple3); -- equals to SELECT empno, sal FROM emp WHERE sal > Tuple1 OR sal > Tuple2 OR sal> Tuple3;
ALL
:满足所有内部条件SELECT empno, sal FROM emp WHERE sal > ALL (SELECT....返回:Tuple1, Tuple2, Tuple3); -- equals to SELECT empno, sal FROM emp WHERE sal > Tuple1 AND sal > Tuple2 AND sal> Tuple3;
3️⃣
EXISIS
:内部查询会返回 True/False \text{True/False} True/False,从而决定外查询执行/不执行SELECT * FROM Buyer WHERE EXISTS( SELECT * FROM Offer -- 内查询中,SELECT什么不重要,因为最后只会输出True/False WHERE Buyer.BuyerID = Offer.BuyerID AND ArtefactID = 1 )
- 先遍历
Buyer
(外表),对其每一行向内Offer
(内表)表查询是否有行满足条件Buyer.BuyerID = Offer.BuyerID AND ArtefactID = 1
- 如果至少有一行条件满足,则执行下列外查询,把满足条件的行打印出来
SELECT * FROM Buyer
- 一行行遍历 + \text{+} +打印后,结果为:
BID \textbf{BID} BID Name \textbf{Name} Name Phone \textbf{Phone} Phone 1 \text{1} 1 Magg \text{Magg} Magg 0333 \text{0333} 0333 2 \text{2} 2 Nicole \text{Nicole} Nicole 0444 \text{0444} 0444 3.4. \textbf{3.4. } 3.4. 其他 SQL \textbf{SQL} SQL子句
1️⃣
COALESCE()
: 返回列表中第一个非NULL值-- 遍历每一行,如果A2非空则返回A2,如果A2空则返回''(首个非空值) SELECT A1, COALESCE(A2, '') AS A2New, A3 FROM users;
初始表格 A1 \textbf{A1} A1 A2 \textbf{A2} A2 A3 \textbf{A3} A3 查询结果 A1 \textbf{A1} A1 A2New \textbf{A2New} A2New A3 \textbf{A3} A3 / \text{/} / John \text{John} John NULL \text{NULL} NULL Doe \text{Doe} Doe / \text{/} / John \text{John} John Doe \text{Doe} Doe / \text{/} / Jane \text{Jane} Jane A. \text{A.} A. Smith \text{Smith} Smith / \text{/} / Jane \text{Jane} Jane A. \text{A.} A. Smith \text{Smith} Smith / \text{/} / Emily \text{Emily} Emily NULL \text{NULL} NULL Davis \text{Davis} Davis / \text{/} / Emily \text{Emily} Emily Davis \text{Davis} Davis 2️⃣
LENGTH()
: 求出一段字符串的长度ORDER BY LENGTH(Steing) -- String长度从小到大排列 ORDER BY LENGTH(Steing) ASC -- String长度从小到大排列 ORDER BY LENGTH(Steing) DEC -- String长度从大到小排列
3️⃣
CASE WHEN
语法
- 语法
CASE WHEN <条件表达式> THEN <条件满足时返回这个值> <条件不满足时返回这个值> END
- 不重命名示例
SELECT id, amount, CASE WHEN amount > 100 THEN 'High' ELSE 'Low' END CASE WHEN amount > 100 THEN 'High' ELSE 'Low' END AS class -- 重命名 FROM orders;
不重命名 id
CASE
amount
重命名 id
CASE
class
/ \text{/} / 1 \text{1} 1 High \text{High} High 150 \text{150} 150 / \text{/} / 1 \text{1} 1 High \text{High} High 150 \text{150} 150 / \text{/} / 2 \text{2} 2 Low \text{Low} Low 80 \text{80} 80 / \text{/} / 2 \text{2} 2 Low \text{Low} Low 80 \text{80} 80 / \text{/} / 3 \text{3} 3 High \text{High} High 120 \text{120} 120 / \text{/} / 3 \text{3} 3 High \text{High} High 120 \text{120} 120 4️⃣ Set Operation: \text{Set Operation:} Set Operation: 目的是合并两个查询结果,原理详见关系代数
SELECT sid, sname, rating, age FROM S1 -- 此操作去除重复行 UNION SELECT sid, sname, rating, age FROM S2; SELECT sid, sname, rating, age FROM S1 -- 此操作保留重复行 UNION ALL SELECT sid, sname, rating, age FROM S2;
4. 补充 Data Type \textbf{4. }补充\textbf{Data Type} 4. 补充Data Type
4.1. \textbf{4.1. } 4.1. 字符类型
1️⃣概述
类型 存储 备注 CHAR(M)
定长字符串 M∈(0,255) \text{M∈(0,255)} M∈(0,255)表示字符长度 VARCHAR(M)
变长字符串 M∈(1,65535) \text{M∈(1,65535)} M∈(1,65535) BIT/BOOL/CHAR
同 CHAR(1)
N/A \text{N/A} N/A BLOB
二进制文件==(音视频)== 存储最多 65535 \text{65535} 65535字节的 0/1 \text{0/1} 0/1序列 TEXT
大段文字 最多 65535 \text{65535} 65535个字符 ENUM(a,b,c...)
列表(多选一) 列表中最多 65535 \text{65535} 65535个成员,索引从左到右/从 0 \text{0} 0开始 SET(a,b,c...)
列表(多选多) 列表中最多 64 \text{64} 64个成员 2️⃣补充
CHAR(M)
中对于定长字符,如果长度不够则会用空格填充Name CHAR(5) -- 如果赋值Name='Kan'则实际存储Name='Kan<空格><空格>'
TEXT
中说的是最多 65535 \text{65535} 65535字符,不是字节;一个字符可占 1-4 \text{1-4} 1-4字节SET(a,b,c...)
示例SET(a1,a2,a3) -- 可存储<空>/a1/a1a2/a1a2a3
4.2. \textbf{4.2. } 4.2. 整数类型
1️⃣概述
Type \textbf{Type} Type Signed Range \textbf{Signed Range} Signed Range Unsigned Range \textbf{Unsigned Range} Unsigned Range TINYINT[(M)]
− 128 → 127 -128\to127 −128→127 0 → 255 0\to255 0→255 SMALLINT[(M)]
− 32768 → 32767 -32768\to32767 −32768→32767 0 → 65535 0\to65535 0→65535 INT[(M)]/INTEGER[(M)]
… … BIGINT[(M)]
… … 2️⃣示例:
TINYINT(4)
- 数字显示宽度为 4 \text{4} 4
- 如果存储的数字为 12 \text{12} 12,则会显示为 0012 \text{0012} 0012
4.3. \textbf{4.3. } 4.3. 实数类型
1️⃣概述
Type \textbf{Type} Type Precision \textbf{Precision} Precision 存储类型 FLOAT[(M,D)]
单精度 Binary \text{Binary} Binary DOUBLE[(M,D)]
双精度(范围更大) Binary \text{Binary} Binary REAL[(M,D)]
双精度(范围更大) Binary \text{Binary} Binary DECIMAL[(M[,D])]
定点类型 字符串 2️⃣参数含义
M
: 小数点左右加起来,一共有多少位D
: 小数位数4.4. Data & Time Type \textbf{4.4. Data \& Time Type} 4.4. Data & Time Type
Type \textbf{Type} Type Format \textbf{Format} Format Range \textbf{Range} Range DATA
YYYY-MM-DD \small\text{YYYY-MM-DD} YYYY-MM-DD 1000-01-01 → 9999-12-31 \text{1000-01-01}\to\text{9999-12-31} 1000-01-01→9999-12-31 TIME
HH:MM:SS \small\text{HH:MM:SS} HH:MM:SS -838:59:59 → 838:59:59 \text{-838:59:59}\to\text{838:59:59} -838:59:59→838:59:59 DATETIME
YYYY-MM-DD HH:MM:SS \small\text{YYYY-MM-DD HH:MM:SS} YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 → 9999-12-31 23:59:59 \text{1000-01-01 00:00:00}\to\text{9999-12-31 23:59:59} 1000-01-01 00:00:00→9999-12-31 23:59:59 TIMESTAMP
YYYY-MM-DD HH:MM:SS \small\text{YYYY-MM-DD HH:MM:SS} YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:00 UTC → 2037 \text{1970-01-01 00:00:00 UTC}\to\text{2037} 1970-01-01 00:00:00 UTC→2037 YEAR[4]
YYYY \small\text{YYYY} YYYY 1901 → 2155 \text{1901}\to\text{2155} 1901→2155 1️⃣
TIMESTAMP
是 DB \text{DB} DB记录的时间点,会将时间转换为当地时间2️⃣
NOW()
函数会以 YYYY-MM-DD HH:MM:SS \text{YYYY-MM-DD HH:MM:SS} YYYY-MM-DD HH:MM:SS格式返回当前时间