資料庫 — SQL 語言
1 SQL 基本概念
1.1 SQL 概念及分類
-
定義:
SQL
是Structured Query Language
的縮寫,意思是結構化查詢語言,是一種在資料庫管理系統中查詢或對資料庫裡面的資料進行更改的語言 -
主流資料庫管理系統
- 關係型資料庫
MySQL
Oracle
Postgre SQL
SQL Server
- 非關係型資料庫
redis
mongo DB
- 關係型資料庫
-
資料定義語言
DDL(Data Ddefinition Language)
- SQL 資料定義語言主要用來定義邏輯結構,包括定義基表,檢視和索引刪除表定義表修改表
-
資料查詢語言
DQL(Data Query Language)
- SQL 的資料查詢語言主要用來對資料庫中的各種資料物件進行查詢
-
資料操縱語言
DML(Data Manipulation Language)
- SQL 的資料操縱語言,用於改變資料庫中的資料,包括插入,刪除,修改
-
資料控制功能
DCL(Data Control Language)
- SQL 的資料控制語言,對錶和檢視的授權,完整性規則的描述以及事務開始和結束等控制語句
1.2 SQL 語言的特點
- 綜合統一:獨立完成資料庫生命週期中的全部活動,包括定義關係模式、錄入資料、建立資料庫、査詢、更新、維護、資料庫重構、資料庫安全
- 高度非過程化:使用者只需提出“做什麼”,而不必指明“怎麼做
- 面向集合的操作方式:SQL 採用集合操作方式
- 以同一種語法結構提供兩種使用方式:SQL既是自含式語言,又是嵌入式語言,SQL語句能夠嵌入到高階語言程式中
- 語言簡潔,易學易用:SQL 語言語法簡單,接近英語口語
1.3 SQL 基本語法
1 SQL 資料型別
資料型別 | 含義 |
---|---|
CHAR(n) CHARACTER(n) |
長度為 n 的定長字串 |
VARCHAR(n) CHARACTERVARYING(n) |
最大長度為 n 的變長字串 |
CLOB | 字串大物件 |
BLOB | 二進位制大物件 |
INT INTEGER |
長整數(4 位元組) |
SMALLINT | 短整數(2 位元組) |
BIGINT | 大整數(8 位元組) |
資料型別 | 含義 |
---|---|
NUMERIC(p, d) | 定點數,由 p 位數字(不包括符號、小數點)組成, 小數點後邊有 d 位數字 |
DECIMAL(p, d) DEC(p, d) |
同 NUMERIC |
REAL | 取決於機器精度的單精度浮點數 |
DOUBLE PRECISION | 取決於機器精度的雙精度浮點數 |
FLOAT(n) | 可選精度的浮點數,精度至少為 n 位數字 |
BOOLEAN | 邏輯布林值 |
DATE | 日期,包含年、月、日,格式為 YYYY-MM-DD |
TIME | 時間,包含一日的時、分、秒,格式為 HH:MM:SS |
TIMESTAMP | 時間戳型別 |
TIMERVAL | 時間間隔型別 |
2 模式的定義及刪除
-
模式定義
- 語法:
CREATE SCHEMA <模式名> AUTHORIZATION <使用者名稱>
- 例子:
CREATE SCHEMA "S-T" AUTHORIZATION WANG;
- 語法:
-
模式定義 + 檢視
- 語法:
CREATE SCHEMA <模式名> AUTHORZATION <使用者名稱> [<表定義子句>|<檢視定義子句>|<授權定義子句>];
- 語法:
-
模式刪除
- 語法:
DROP SCHEMA <模式名><CASCADE|RESTRICT>;
CASCADE、RESTRICT
兩者必須二選一VASCADE(級聯)
:刪除模式的同時也把給模式的所有資料庫物件刪除RESTRICT(限制)
:如果該模式下有下屬物件(比如表檢視),則拒絕該刪除語句的執行
- 語法:
3 表的增刪改查
- 建立表
CREATE TABLE 表名 (欄位名 型別 欄位約束, 欄位名 型別 欄位約束, 欄位名 型別 欄位約束);
CREATE TABLE Student (
name VARCHAR(20),
age INT,
sex CHAR(1),
);
- 刪除表
DROP TABLE <表名> [RESTRICT|CASCADE];
DROP TABLE Student RESTRICT;
- 修改
ALTER TABLE <表名>
[ADD [COLUMN] <新列名><資料型別> [完整性約束]]
[ADD <表級完整性約束>]
ALTER TABLE Student ADD S_entrance DATE;
ALTER TABLE Student ALTER COLUMN S_age INT;
4 索引的增刪改查
- 當資料庫中資料量巨大時,建立索引可以減少查詢時間,索引可以建立在一列或多列上
- 建立索引
CLUSTER
:聚簇索引,物理順序與索引的邏輯順序相同UNIQUE
:唯一索引
CREATE [UNIQUE] [CLUSTER] INDEX <索引名>
ON <表名>(<列名>[<次序>][,<列名> [<次序>]] ...);
CREATE UNIQUE INDEX Stusno ON Student(Sno);
- 修改索引
ALTER INDEX <舊索引名> RENAME TO <新索引名>;
ALTER INDEX SCno RENAME TO SCSno;
- 刪除索引
DROP INDEX <索引名>
DROP INDEX Stusno;
2 SQL 的查詢
假設關係表
Student
、Course
、SC
如下:
Student
學號(Sno) | 姓名(Sname) | 性別(Ssex) | 年齡(Sage) | 院系(Sdept) |
---|---|---|---|---|
201215121 | 李勇 | 男 | 20 | CS |
201215122 | 劉晨 | 女 | 19 | CS |
201215123 | 王敏 | 女 | 18 | MA |
201215125 | 張力 | 男 | 19 | ES |
Course
課程號(Cno) | 課程名(Cname) | 先行課(Cpno) | 學分(Ccredit) |
---|---|---|---|
1 | 資料庫 | 5 | 4 |
2 | 數學 | / | 2 |
3 | 資訊系統 | 1 | 4 |
4 | 作業系統 | 6 | 3 |
5 | 資料結構 | 7 | 4 |
6 | 資料處理 | / | 2 |
7 | Java語言 | 6 | 4 |
SC
學號(Sno) | 課程號(Cno) | 成績(Grade) |
---|---|---|
201215121 | 1 | 92 |
201215121 | 2 | 85 |
201215121 | 3 | 88 |
201215122 | 2 | 90 |
201515122 | 3 | 80 |
2.1 查詢所有列
查詢
Student
表中所有列
SELECT * FROM Student;
2.2 查詢部分列
查詢
Student
表中的Sno
、Ssex
列
SELECT Sno, Ssex FROM Student;
2.3 列取別名
查詢
Student
表中的Sno
、Ssex
列,並將Sno
命名為 “學號”,Ssex
命名為 “性別”
SELECT Sno 學號, Ssex 性別 FREOM Student;
SELECT Sno AS 學號, Ssex AS 性別 FROM Student;
2.4 表取別名
查詢
Course
表中的Cno
列,並將查詢結果命名為CC
SELECT Cno FROM Course AS CC;
2.5 查詢結果去重
查詢
SC
中的Sno
列,並將結果去重
SELECT DISTINCT Sno AS 課程名 FROM SC;
2.6 查詢結果加條件
- 查詢條件如下:
查詢條件 | 謂詞 |
---|---|
比較 | \(=、>、<、\le、\ge、!=、<>、!>、!<、NOT\) |
確定範圍 | \(BETWEEN AND、NOT BETWEEN AND\) |
確定集合 | \(IN、NOT IN\) |
字元匹配 | \(LIKE、NOT LIKE\) |
空值 | \(IS NULL、IS NOT NULL\) |
邏輯運算 | \(AND、OR、NOT\) |
查詢 SC 表中 Grade 大於 88 的資訊
SELECT * FROM SC WHERE Grade >= 88;
查詢 SC 表中 Grade 在 85 ~ 95 之間的資訊
SELECT * FROM SC WHERE Geade BETWEEN 85 AND 95;
查詢 1 是否包含在 (1,2) 之間
SELECT 1 FROM (1, 2);
查詢 Course 表中包含 “系統” 的課程的課程號,課程名
"%" 可以近似多個字元,"_" 只能近似一個字元
SELECT Cno, Cname FROM Course WHERE Cname LIKE '%系統';
查詢 Course 中先行課為空的資訊
SELECT * FROM Course WHERE Cpno IS NULL;
查詢 Course 中學分為 4 分並且先行課為 1 的課程的課程名
SELECT Cname FROM Course WHERE Ccredit = 3 AND Cpno = 1;
查詢 Course 中學分為 4 分或 3 分的課程的課程名
SELECT Cname FROM Course WHERE Ccredit = 3 OR Ccredit = 4;
2.7 聚集函式
函式 | 含義 |
---|---|
\(COUNT(*)\) | 統計元組個數 |
$COUNT([DISTINCT | ALL]<列名>)$ |
$SUM([DISTINCT | ALL]<列名>)$ |
$AVG([DISTINCT | ALL]<列名>)$ |
$MAX([DISTINCT | ALL]<列名>)$ |
$MIN([DISTINCT | ALL]<列名>)$ |
注:
DISTINCT
是去除重複的值
查詢 CS 表中 Grade 的個數(去重)、總和、平均值、最值
SELECT COUNT(*) FROM SC;
SELECT COUNT(DISTINCT Grade) FROM SC;
SELECT SUM(Grade) FROM SC;
SELECT AVG(Grade) FROM SC;
SELECT MAX(Grade) FROM SC;
SELECT MIN(Grade) FROM SC;
2.8 分組查詢
將表 SC 按照 Sno 進行分組,然後篩選出分組中 Sno 為 "201215121" 的一組
SELECT Sno FROM SC GROUP BY Sno HAVING Sno = '201215121';
2.9 等值連線
將 Student 與 SC 以 Sno 進行等值連線
SELECT Student AS S, SC WHERE S.Sno = SC.Sno;
2.10 自身連線
將 Student 表與自生進行連線
SELECT Student AD S1, Student AS S2 WHERE S1.Sno = S2.Sno;
2.11 外連線
將 Course 與 SC 以 Cno 分別進行外連線、左外連線、右外連線
SELECT * FROM Course OUTER JOIN SC ON Course.Cno = SC.Cno;
SELECT * FROM Course LEFT OUTER JOIN SC ON Course.Cno = SC.Cno;
SELECT * FROM Course RIGHT OUTER JOIN SC ON Course.Cno = SC.Cno;
2.12 多表查詢
將 Student 與 SC 以 Sno 進行連線,並且將 Course 與 SC 以 Cno 進行等值連線
SELECT *
FROM Student JOIN SC ON Student.Sno = SC.Sno
JOIN Course ON SC.Cno = Course.Cno;
SELECT *
FROM Student, Course, SC
WHERE Student.Sno = SC.Sno AND Course.Cno = SC.Cno;
2.13 巢狀查詢
查詢 Grade > 90 的學生的學號(Sno)、姓名(Sname)、所在院系(Sdept)
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sno IN (
SELECT Sno
FROM SC
WHERE Grade > 90;
);
2.14 帶有 ANY 的查詢
查詢 Sage > 19 的所有學生的姓名(Sname)(結果滿足子集中的任一值即可)
SELECT Sname
FROM Student
WHERE Sage > ANY (
SELECT Sage
FROM Student
WHERE Sage > 19;
);
2.15 帶有 ALL 的查詢
查詢 Sage > 19 的所有學生的學號(Sno)(結果要滿足子集中的所有值)
SELECT Sno
FROM Student
WHERE Sage > ALL (
sELECT Sage
FROM Student
WHERE Sage > 19;
);
2.16 帶 EXISTS 的查詢
查詢沒有一門課不選修的學生的姓名(Sname)
SELECT Sname
FROM Student
WHERE NOT EXISTS(
SELECT *
FROM Course
WHERE NOT EXISTS (
SELECT *
FROM SC
WHERE Sno = Student.Sno AND Cno = Course.Cno);
);
)
2.17 集合查詢
1 並集
查詢所在系(Sdept)為 "CS" 的學生與年齡(Sage)大於 19 的學生的並集
SELECT * FROM Student WHERE Sdept = "CS"
UNION
SELECT * FROM Student WHERE Sage > 19;
2 交集
查詢所在系(Sdept)為 "CS" 的學生與年齡(Sage)大於 19 的學生的交集
SELECT * FROM Student WHERE Sdept = "CS"
INTERSECT
SELECT * FROM Student WHERE Sage > 19;
3 差集
查詢所在系(Sdept)為 "CS" 的學生與年齡(Sage)大於 19 的學生的差集
SELECT * FROM Student WHERE Sdept = "CS"
EXCEPT
SELECT * FROM Student WHERE Sage > 19;
3 SQL 的增刪改
3.1 資料的插入
1 標準新增
INSERT INTO Student(Sno, Sname, Ssex, Sage, Sdept)
VALUES ('201215128', '石昊', '男', 25, 'IS');
2 指定部分欄位
INSERT INTO Student (Sname, Sage, Sdept) VALUE ('葉凡', 22, 'CS');
3 不指定欄位
-- 不指定欄位時,需要一一對應新增且不能缺少專案
INSERT INTO VALUE Student ('201215128', '石昊', '男', 25, 'IS');
4 批量新增
INSERT INTO Student VALUES
('201215128', '石昊', '男', 25, 'IS'),
('201215129', '葉凡', '男', 22, 'CS'),
('201215130', '狠人', '女', 20, 'MX');
3.2 修改
將 Student 表中學號(Sno)為 "201215122" 的學生姓名(Sname)改為 “石昊”,年齡(Sage)改為 25
UPDATE Student SET Sname = "石昊", Sage = 25 WHERE Sno = "201215122";
3.3 刪除
刪除 Student 表中年齡(Sage)大於 18 的資料
DELETE FROM Student WHERE Sage > 18;
4 檢視
4.1 檢視定義
- 檢視(VIEW)也被稱作虛表,即虛擬的表,是一組資料的邏輯表示,其本質是對應於一條 SQL 語句,結果集被賦予一個名字
- 檢視本身並不包含任何資料,它只包含對映到基表的一個查詢語句,當基表資料發生變化,檢視資料也隨之變化
- 目的:方便,簡化資料操作
- 當我們業務需求要查出多張表的資料,這時我們可能會關聯多張表查詢處理,如果這個查詢 SQL 複雜的話也影響了查詢效率,這個時候就可以建立檢視,查詢時候只需要
select * from view
就可以
4.2 建立檢視
-- 末尾的 WITH CHECK OPTION 作用如下:
-- 當後續操作對檢視進行增刪改操作時,可能檢視已經不滿足子條件 S 的約束
-- 加上該語句之後,後續對檢視進行增刪改的時,系統會自動在該子條件 S 下進行操作
CREATE VIEW S_STU
AS <子查詢>
[WITH CHECK OPTION];
將 Student 表中學生年齡(Sage)> 18 的學生建立一個名為 S_NEW 的檢視,該檢視包含學生的學號(Sno)、姓名(Sname)、性別(Ssex)、所在院系(Sdept)
CREATE VIEW S_NEW
AS
SELECT Sno, Sname, Ssex, Sdept
FROM Student
WHERE Sage > 18
WITH CHECK OPTION;
4.3 刪除檢視
-- CASCADE 的作用如下:
-- 當加上該語句時,會刪除該檢視以及其下的所有檢視
-- 當不加該語句時,若該檢視下該有其他檢視,會刪除失敗
DROP VIEW <檢視名> [CASCADE];
刪除 4.2 建立的檢視 S_NEW
DROP VIEW S_NEW CASCADE;
4.4 查詢檢視
查詢 4.2 檢視 S_NEW 中性別(Ssex)為 “女” 的學生的學號(Sno)
SELECT Sno
FROM S_NEW
WHERE Ssex = "女";
4.5 檢視更新
- 檢視是虛擬的,不存在的,所以對於檢視的操作,最終會反映到基本表上
將 4.2 的檢視 S_NEW 中所在系(Sdept)為 “CS” 學生的性別(Ssex)全改為 “男”
-- 更新檢視
UPDATE S_NEW
SET Ssex = "男"
WHERE Sdept = "CS";
-- 更新基本表
-- 因為 4.2 的檢視建立條件是 Sage > 18,因此更新基本表時要加上該條件
UPDATE Student
SET Ssex = "男"
WHERE Sdept = "CS" AND Sage > 18;