笔记分享: 墨尔本大学INFO20003数据库系统——02. SQL概述

文章目录


更多 资料笔记

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.合并两表所有Tuple 2.去除重复项
Intersection \text{Intersection} Intersection ∩ \cap 原关系 1 + 1+ 1+原关系 2 2 2 → 2. 去除重复项 1. 提取两个表都出现的Tuple \large\xrightarrow[2. 去除重复项]{1. 提取两个表都出现的\text{Tuple}} 1.提取两个表都出现的Tuple 2.去除重复项
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 ClausesAND → Λ, OR → V
  1. 示例: σ rating ≥ 9   ∧  age<50 ( S 2 ) \sigma_{\text{rating}\geq{}9\text{ }\land{}\text{ age<50}}(\text{S}_2) σrating9  age<50(S2)
    SELECT * FROM S2 
    WHERE rating >= 9 AND age < 50;
    
  2. 注意事项
    • 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(π)

  1. 操作:仅保留 Projection List \text{Projection List} Projection List中的列 → \to{} 去除重复的行
  2. 特点: 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.
  3. 示例:注意 SQL \text{SQL} SQL中可控制投影后去不去出重复项,但 Relational Algebra \text{Relational Algebra} Relational Algebra默认去除重复项
    SELECT * FROM Student; -- 选中所有列(左表)
    SELECT age FROM Student; -- 选中年龄这一列,但是SQL操作中默认不去除重复项(中表)
    SELECT DISTINCT age FROM Student; -- 选中年龄这一列,删除重复项(右表)
    
    1711891750690

2️⃣ Selection ( σ ) \text{Selection}(\sigma{}) Selection(σ)

  1. 操作:仅保留 Selection \text{Selection} Selection条件的行,并且不会有任何重复行
  2. 示例:在 SQL \text{SQL} SQL中体现在WHERE
    SELECT * FROM Student WHERE Student.rating >= 9;
    
    image-20240401025827011

3️⃣ Projection ( π )  & Selection ( σ ) \text{Projection}(\pi{})\text{ \& Selection}(\sigma{}) Projection(π) & Selection(σ)

  1. 注意事项
    • 一般先 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} AB
  2. 示例:在 SQL \text{SQL} SQL中体现在WHERESELECT
    SELECT sname, rating FROM Student WHERE Student.rating >= 9;
    
    image-20240401031241564

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):

  1. 两表 Column \text{Column} Column数一致,相应的列的 Data Type \text{Data Type} Data Type相同
    • 两表属性名不一定要相同, SQL \text{SQL} SQL默认取上表的名
  2. 该条件适用 Union/Set Difference/Intersection \text{Union/Set Difference/Intersection} Union/Set Difference/Intersection三者

1️⃣ Union: \text{Union:} Union:

  1. 操作:将两表上下拼接在一起,并在 Relational Algebra \text{Relational Algebra} Relational Algebra中默认消除重复项
  2. 特性:对称性( Symmetric \text{Symmetric} Symmetric)
  3. 示例:在 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;
    
    1711902909279

2️⃣ Set-Difference: \text{Set-Difference:} Set-Difference:

  1. 操作:从一个关系中,删除另一个关系中存在的 Tuple \text{Tuple} Tuple
  2. 特性:无对称性( Asymmetric \text{Asymmetric} Asymmetric)
  3. 示例: 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
    );
    
    1711902909279

3️⃣ Intersection: Compound Operator \text{Intersection: Compound Operator} Intersection: Compound Operator

  1. 操作:找出两个关系中共存的 Tuples \text{Tuples} Tuples,本质上是混合运算 R ∩ S ≡ R − ( R − S ) \text{R}\cap{}\text{S}\equiv\text{R}-(\text{R}-\text{S}) RSR(RS)
  2. 示例:注意操作有对称性;同样也需要用 SQL \text{SQL} SQL子查询变相实现
    SELECT sid, sname, rating, age
    FROM S1
    WHERE (sid, sname, rating, age) IN (
        SELECT sid, sname, rating, age
        FROM S2
    );
    
    1711902909279

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️⃣操作:

  1. 用一个表的每行,依次去扫描另一个表的每一行,输出组合
  2. 结果会保留所有的列(即使重名了,也不要紧)
    1711902909279

2️⃣重命名 ρ \rho{} ρ

  1. 合并后的属性名称可能一样,由此需要重命名
  2. 比如 ρ ( C ( 1 → sid1 , 5 → sid2 ) , R × S ) \rho{(\text{C}(1\to{\text{sid1}},5\to{\text{sid2}}),\text{R}×\text{S}}) ρ(C(1sid1,5sid2),R×S)
    1711908813683
    • 1 → sid1 1\to{\text{sid1}} 1sid1的意思是:第一列改成 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}) RConditionS=σCondition(R×S)

  1. 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
    1711902909279
  2. 再筛选满足 (R.sid<S.sid) {\text{(R}\text{.sid<S}\text{.sid)}}\text{} (R.sid<S.sid)的行
    1711908813683
  3. 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

image-20240401231354398
  1. 原理/计算步骤
    • 先计算 R × S \text{R}×\text{S} R×S,找到两组(一组一或多个)名字相同的 Column \text{Column} Column(此处为 sid \text{sid} sid)
      1711902909279
    • 筛选两同名列值相同的行,然后只保留其中一列。即为 R ⋈ S ≡ R ⋈ R.sid=S.sid S \text{R}\bowtie{}\text{S}\equiv\text{R}\bowtie{_{\text{R.sid=S.sid}}}\text{S} RSRR.sid=S.sidS
      image-20240401054601363
  2. 注意事项:多个 Column \text{Column} Column相同匹配时,NATURAL JOIN要多列相等
    image-20240616094428222
    即为 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} RSRR.sid=S.sid  R.bid=S.bidS
  3. SQL:  \text{SQL: } SQL: ⚠️⚠️⚠️没有 Column \text{Column} Column相同匹配时,NATURAL JOIN语句会被执行为 Cross Product \text{Cross Product} Cross Product
    SELECT * 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(条件是等式)

image-20240401231354398
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

image-20240519224425895

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
  1. Left Outer Join: \text{Left Outer Join:} Left Outer Join: Customer.CustomerID = 3时有表无匹配,所以代之以 NULL \text{NULL} NULL
    SELECT * 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
  2. Right Outer Join: \text{Right Outer Join:} Right Outer Join: Account.CustomerID = 4时有表无匹配,所以代之以 NULL \text{NULL} NULL
    SELECT * 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
  3. 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} 1AName1 / \text{/} / 101 \text{101} 101 1 \text{1} 1BName1 / \text{/} / 1001 \text{1001} 1001CType1BName2
/ \text{/} / 2 \text{2} 2AName2 / \text{/} / 102 \text{102} 102 1 \text{1} 1BName2 / \text{/} / 1002 \text{1002} 1002CType2BName3
/ \text{/} / / \text{/} / / \text{/} / / \text{/} / 201 \text{201} 201 2 \text{2} 2BName3 / \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} 1AName1 101 \text{101} 101 1 \text{1} 1BName1
1 \text{1} 1AName1 102 \text{102} 102 1 \text{1} 1BName2
2 \text{2} 2AName2 201 \text{201} 201 2 \text{2} 2BName3

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} 1AName1 101 \text{101} 101 1 \text{1} 1BName2 1001 \text{1001} 1001CType1BName2
2 \text{2} 2AName2 201 \text{201} 201 2 \text{2} 2BName3 1002 \text{1002} 1002CType2BName3

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操作

image-20240520005817353
-- 创建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)
);
  1. 关于 Key \text{Key} Key
    • 要用PRIMARY KEY指定哪个变量时主键
    • 要用FOREIGN KEY REFERENCES指定 Foreign Key \text{Foreign Key} Foreign Key引用的哪个变量,否则会 Syntax Error \text{Syntax Error} Syntax Error
  2. 补充事项
    • AUTO_INCREMENT: 用来标记主键字段,插入一个记录后被标记字段自动 +1 \text{+1} +1
    • ENUM: 枚举数据类型类型,只允许属性为预设值

2️⃣修改表格系列操作

操作关键字
增加表格的 Attributes \text{Attributes} AttributesALTER TABLE <表名> ADD <属性名> <属性类型>
减少表格的 Attributes \text{Attributes} AttributesALTER 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;

👽REPLACEINSERT功能几乎一致,区别仅仅在于,当待插入记录的 PK ↔ 冲突 相同 \text{PK}\xleftrightarrow[冲突]{相同} PK相同 冲突已存在记录的 PK \text{PK} PK

  1. INSERT:操作费费,插入失败
  2. 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;
  1. 子句执行的顺序会影响结果
  2. 没有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️⃣最基本结构:

  1. 投影,原理详见关系代数
    SELECT * FROM Student; -- 选中所有列, Heap Scan
    SELECT age FROM Student; -- 选中年龄这一列,但是SQL操作中默认不去除重复项
    
  2. 关于DISTINCT,其后所有属性都要删除重复项
    SELECT DISTINCT age FROM Student; -- 选中年龄这一列,删除重复项
    SELECT DISTINCT age,name FROM Student; -- 年龄+姓名的组合要DISTINCT,删除重复项
    

2️⃣聚合函数 Aggregare Function \text{Aggregare Function} Aggregare Function

  1. 概述
    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
  2. 示例
    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
  3. SUM()补充:
    • 当用于数值类型属性时,会遍历每行求出并返回总和
    • 当用于布尔类型属性时,会遍历每行(布尔真 =1/ \text{=1/} =1/布尔假 =0 \text{=0} =0),返回总和

3️⃣重命名子句AS Clause \text{Clause} Clause

SELECT 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原理详见关系代数部分

  1. Cross-Product \text{Cross-Product} Cross-Product
    SELECT * FROM R, S;	-- Cross product between R, S
    
  2. 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. 匹配的关键字
    1 \textbf{1} 1个不确定的字符 0-M \textbf{0-M} 0-M个不确定的字符
    _ \text{\_} _ % \text{\%} %
  2. 匹配子句示例
    Clause \textbf{Clause} ClauseCustomerName 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} axxaxxx
    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
  3. 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:

  1. 讲记录根据一个/多个属性,分为若干小组
  2. 通常和聚合函数结合使用,为每个小组计算出独立结果
  3. 示例
    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{/} /
  4. 复杂一些的例子: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一起出现

  1. 作用:作为聚合函数的补充,用于筛选GROUP BY出来的组
  2. 对比:
    HAVING Clause \textbf{Clause} ClauseWHERE Clause \textbf{Clause} Clause
    后接关系 Attribute \text{Attribute} Attribute有关条件后接聚合函数(数结)果有关条件
  3. 示例:注意区分WHEREHAVING
    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} AveBalanceHAVING 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:

  1. 将查询得到的结果按照某一属性排序
    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; -- 降序
    
  2. 将查询得到的结果按照符合属性排序
    SELECT Name, Type FROM Customer
    ORDER BY Name DESC, Type ASC;
     -- 先按Name降序排序
     -- 再对于Name相同的Tuple,按照Type升序排序
    

2️⃣LIMIT/OFFSET Clause: \text{Clause:} Clause:

  1. 含义
    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
  2. 示例:
    40817826335
    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️⃣概述

  1. SELECT结构相当于一个查询,在一个SELECT中插入另一个SELECT,则后者就是前者子查询
  2. 执行顺序:先执行子查询 → \to{} 将子查询结果传给主查询 → \to{} 执行主查询
  3. 相关子查询:子查询可以直接使用主(外层)查询的列/值

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️⃣示例表格

image-20240402032453333
  1. 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
  2. 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)
  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
  2. 基于 Join \text{Join} Join的优化:执行的效率会更高
    ELECT Buyer.*
    FROM Buyer JOIN Offer ON Buyer.BID = Offer.BID
    WHERE Offer.AID = 1;
    

2️⃣ANY/ALL/EXISTS

  1. 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;
    
  2. 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
)
  1. 先遍历Buyer(外表),对其每一行向内Offer(内表)表查询是否有行满足条件
     Buyer.BuyerID = Offer.BuyerID AND ArtefactID = 1
    
  2. 如果至少有一行条件满足,则执行下列外查询,把满足条件的行打印出来
     SELECT * FROM Buyer
    
  3. 一行行遍历 + \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语法

  1. 语法
    CASE WHEN <条件表达式> THEN <条件满足时返回这个值> <条件不满足时返回这个值> END
    
  2. 不重命名示例
    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;
    
    不重命名idCASEamount重命名idCASEclass
    / \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/CHARCHAR(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️⃣补充

  1. CHAR(M)中对于定长字符,如果长度不够则会用空格填充
    Name CHAR(5) -- 如果赋值Name='Kan'则实际存储Name='Kan<空格><空格>'
    
  2. TEXT中说的是最多 65535 \text{65535} 65535字符,不是字节;一个字符可占 1-4 \text{1-4} 1-4字节
  3. 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 128127 0 → 255 0\to255 0255
SMALLINT[(M)] − 32768 → 32767 -32768\to32767 3276832767 0 → 65535 0\to65535 065535
INT[(M)]/INTEGER[(M)]
BIGINT[(M)]

2️⃣示例:TINYINT(4)

  1. 数字显示宽度为 4 \text{4} 4
  2. 如果存储的数字为 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️⃣参数含义

  1. M: 小数点左右加起来,一共有多少位
  2. 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-019999-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:59838: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:009999-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 UTC2037
YEAR[4] YYYY \small\text{YYYY} YYYY 1901 → 2155 \text{1901}\to\text{2155} 19012155

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格式返回当前时间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值