聲明:全文來源《mysql SQL必知必會(第3版)》 第一章 瞭解SQL 1.1 資料庫基礎 資料庫(database)保存有組織的數據的容器 表(table)某種特定類型數據的結構化清單。資料庫中的每個表都有一個用來標識自己的名字。此名字是唯一的。 模式(schema)關於資料庫和表的佈局及特性 ...
聲明:全文來源《mysql SQL必知必會(第3版)》
第一章 瞭解SQL
1.1 資料庫基礎
資料庫(database)保存有組織的數據的容器
表(table)某種特定類型數據的結構化清單。資料庫中的每個表都有一個用來標識自己的名字。此名字是唯一的。
模式(schema)關於資料庫和表的佈局及特性的信息。
列(column)表中的一個欄位。所有表都是由一個或多個列組成的。
數據類型(datatype)所容許的數據的類型。每個表列都有相應的數據類型,它限制該列中存儲的數據。
行(row)表中的一個記錄。
主鍵(primary key)一列,其值能夠唯一標識表中每一行。
-
- 任意兩行都不具有相同的主鍵值;
- 每個行都必須具有一個主鍵值(主鍵值不允許NULL值)
- 主鍵列中的值不允許修改或更新
- 主鍵值不嫩惡搞重用(如果某行從表中刪除,它的主鍵不能賦給以後的新行)。
結構化查詢語言(SQL)Structured Query Language
第二章 創建和操縱表
班級信息ClassInfo
班級編號 |
班主任編號 |
學生編號 |
年級 |
ClassID |
TeacherID |
StudentID |
Grade |
學生信息StudentInfo
學生編號 |
性別 |
年齡 |
身份證 |
學生姓名 |
StudentID |
Gender |
Age |
CardID |
StudentName |
學生成績StudentAchieve
學生編號 |
語文 |
數學 |
英語 |
年份 |
班級編號 |
StudentID |
Chinese |
Math |
English |
TestYear |
ClassID |
2.1 創建表
為利用CREATE TABLE創建表,必須給出下列信息:
-
- 新表的名字,在關鍵字CREATE TABLE之後給出;
- 表列的名字和定義,用逗號分隔;
CREATE TABLE ClassInfo ( ClassID CHAR(20) NOT NULL, --班級編號 TeacherID CHAR(20) NOT NULL, --班主任編號 StudentID CHAR(20) NOT NULL, --學生編號 Grade CHAR(15) NOT NULL --年級 )
CREATE TABLE StudentInfo ( StudentID CHAR(20) NOT NULL, --學生編號 StudentName CHAR(50) NOT NULL, --學生姓名 Gender CHAR(5) NOT NULL, --性別 Age INT NOT NULL DEFAULT 0, --年齡 CardID VARCHAR(50) NULL DEFAULT '' --身份證 )
CREATE TABLE StudentAchieve ( StudentID CHAR(20) NOT NULL, --學生編號 ClassID CHAR(20) NOT NULL, --班級編號 Chinese DECIMAL(10,5) NOT NULL DEFAULT 0, --語文 Math DECIMAL(10,5) NOT NULL DEFAULT 0, --數學 English DECIMAL(10,5) NOT NULL DEFAULT 0 --英語 )
2.2 更新表
為更新表定義,可使用ALTER TABLE語句。
為了使用ALTER TABLE更改表結構,必須給出下麵的信息:
-
- 在ALTER TABLE之後給出要更改的表名
- 所做更改的列名
ALTER TABLE dbo.StudentAchieve ADD TestYear CHAR(20) NOT NULL --考試年份
添加考試年份的列
ALTER TABLE dbo.StudentAchieve DROP COLUMN TestYear
刪除考試年份的列
2.3 刪除表
DROP TABLE dbo.StudentAchieve
刪除學生成績這張表。刪除表沒有確認,也不能撤銷,執行這條語句將永久刪除該表。
註:可使用關係規則防止意外刪除
第三章 檢索數據
3.1 檢索單個列
SELECT StudentName FROM dbo.StudentInfo
3.2 檢索多個列
SELECT StudentID,Gender,StudentName FROM dbo.StudentInfo
3.3 檢索所有列
SELECT * FROM dbo.StudentInfo
第四章 排序檢索數據
4.1 排序數據
SELECT StudentName FROM dbo.StudentInfo ORDER BY StudentName
Order by子句的位置:應保證它是slect語句中最後一條子句。
4.2 按多個列排序
SELECT StudentID,Gender,StudentName FROM dbo.StudentInfo ORDER BY StudentName,StudentID
4.3 按列位置排序
SELECT StudentID,Gender,StudentName FROM dbo.StudentInfo ORDER BY 1,3
4.4 指定排序方向
SELECT StudentID,Gender,StudentName FROM dbo.StudentInfo ORDER BY Gender DESC
DESC降序排列,DESCENDING
ASC升序排列,預設
第五章 過濾數據
5.1 使用WHERE子句
SELECT StudentID,StudentName FROM dbo.StudentInfo WHERE Age=5
5.2 where子句操作符
操作符 |
說明 |
= |
等於 |
<> |
不等於 |
!= |
不等於 |
< |
小於 |
<= |
小於等於 |
!< |
不小於 |
> |
大於 |
>= |
大於等於 |
!> |
不大於 |
BETWEEN |
再指定的兩個值之間 |
IS NULL |
為NULL值 |
5.2.1 檢查單個值
SELECT StudentID,ClassID FROM dbo.StudentAchieve WHERE Chinese<95
5.2.2 不匹配檢查
SELECT * FROM dbo.StudentInfo WHERE CardID <>''
5.2.3 範圍值檢查
SELECT StudentID,Math FROM dbo.StudentAchieve WHERE Math BETWEEN 90 AND 100
5.2.4 空值檢查
SELECT StudentName,StudentID FROM dbo.StudentInfo WHERE CardID IS NULL
第六章 高級數據過濾
6.1 組合WHERE子句
6.1.1 AND操作符
SELECT StudentID,StudentName FROM dbo.StudentInfo WHERE Gender='女' AND Age=6
6.1.2 OR操作符
SELECT StudentID,StudentName FROM dbo.StudentInfo WHERE Gender='女' OR Age=6
6.2 IN 操作符
SELECT StudentID,StudentName FROM dbo.StudentInfo WHERE Age IN (5,6)
6.2 NOT操作符
SELECT StudentID,StudentName,Gender FROM dbo.StudentInfo WHERE NOT Gender='女'
第七章 用通配符進行過濾
7.1 LIKE操作符
通配符(wildcard)用來匹配值的一部分的特殊字元。
搜索模式(search pattern)由字面值、通配符或兩者組合構成的搜索條件。
7.1.1 百分號(%)通配符
SELECT StudentID,StudentName,CardID FROM dbo.StudentInfo WHERE CardID LIKE 'card%'
檢索任意以card起頭的詞。
%告訴DBMS接受card之後的任意字元,不管他有多少字元。
SELECT StudentID,StudentName,CardID FROM dbo.StudentInfo WHERE CardID LIKE '%01%'
%可以匹配0個字元。%代表搜索模式中給定位置的0個、1個或多個字元。
7.1.2 下劃線(_)通配符
下劃線的用途與%一樣,但下劃線只匹配一個字元而不是多個字元。
SELECT StudentID,StudentName,CardID FROM dbo.StudentInfo WHERE StudentName LIKE '名_2'
7.1.3 方括弧([])通配符
方括弧通配符用來指定一個字元集,它必須匹配指定位置得一個字元。
SELECT * FROM dbo.StudentInfo WHERE CardID LIKE 'card000[23]%'
找出以card0002或card0003開頭得cardid
此通配符可以用首碼字元^(脫子號)來否定。
SELECT * FROM dbo.StudentInfo WHERE CardID LIKE 'card000[^23]%'
7.2 使用通配符得技巧
-
- 不用過分使用通配符。如果其他操作符能達到相同得目的,應該使用其他操作符。
- 在確實需要使用通配符時,除非絕對又必要,否則不要把它們用在搜索模式得開始處,把通配符置於搜索模式得開始處,搜索起來時最慢的。
- 仔細註意通配符的位置。如果放錯地方,可能不會返回想要的數據。
第八章 創建計算欄位
8.1 計算欄位
欄位(field)基本上與列(column)的意思相同,經常互換使用,不過數據列一般稱為列,而術語欄位通常用在計算欄位的連接上。
8.2 拼接欄位
拼接(concatenate)將值聯結到一起構成單個值。
SELECT StudentID+'name: '+StudentName FROM dbo.StudentInfo
SELECT RTRIM(StudentID)+'name: '+RTRIM(StudentName) FROM dbo.StudentInfo
RTRIM()函數去掉右邊的所有空格。
SELECT RTRIM(StudentID)+'name: '+RTRIM(StudentName) info FROM dbo.StudentInfo
使用別名
8.3 執行算術計算
SELECT StudentID,Chinese+Math+English AS total FROM dbo.StudentAchieve
第九章 使用數據處理函數
9.1 函數
可移植(portable)所編寫的代碼可以在多個系統上運行。
9.2 使用函數
9.2.1 文本處理函數
SELECT StudentID,UPPER(CardID) cardinfo FROM dbo.StudentInfo
UPPER()將文本轉換為大寫
常用的文本處理函數
函數 |
說明 |
LEFT() |
返回串左邊的字元 |
LENGTH() |
返回串的長度 |
LOWER() |
將串轉換為小寫 |
LTRIM() |
去掉串左邊的空格 |
RIGHT() |
返回串右邊的字元 |
RTRIM() |
去掉串右邊的空格 |
SOUNDEX() |
返回串的SOUNDEX值 |
UPPER() |
將串轉換為大寫 |
SOUNDEX()函數是一個將任何文本串轉換為描述其語音表達的字母數字模式的演算法。SOUNDEX考慮了類似的發音字元和音節,使得能對串進行發音比較而不是字母比較。
9.2.2 日期和時間處理函數
日期和時間採用相應的數據類型存儲在表中,每種DBMS都有自己的變體。日期和時間值以特殊的格式存儲,以便能快速和有效地排序或過濾,並且節約物理存儲空間。
9.2.3 數值處理函數
函數 |
說明 |
ABS() |
絕對值 |
COS() |
餘弦 |
EXP() |
指數 |
PI() |
圓周率 |
SIN() |
正弦 |
SQRT() |
平方根 |
TAN() |
正切 |
第十章 彙總數據
10.1 聚集函數
聚集函數(aggregate function)運行在行組上,計算和返回單個值的函數。
函數 |
說明 |
AVG() |
平均值 |
COUNT() |
行數 |
MAX() |
最大值 |
MIN() |
最小值 |
SUM() |
和 |
10.1.1 AVG()函數
SELECT AVG(Chinese) AS avg_chinese FROM dbo.StudentAchieve
SELECT AVG(Chinese) AS avg_chinese_11 FROM dbo.StudentAchieve WHERE ClassID='c00011'
AVG()只能用來確定特定數值列的平均值,而且列名必須作為函數參數給出。只能用於單個列。
AVG()函數忽略值為NULL的行。
10.1.2 COUNT()函數
COUNT()函數又兩種使用方式
-
- 使用COUNT(*)對錶中行的數據進行計數,不管表列中包含的是空值還是非空值。
- 使用COUNT(column)對特定列中具有值得行進行計數,忽略NULL值
SELECT COUNT(*) AS num FROM dbo.StudentInfo
SELECT COUNT(StudentID) AS num FROM dbo.StudentInfo
10.1.3 MAX()函數
SELECT MAX(Math) AS max_math FROM dbo.StudentAchieve
10.1.4 MIN()函數
SELECT MIN(Math) AS min_math FROM dbo.StudentAchieve
10.1.5 SUM()函數
SELECT sum(Math) AS sum_math FROM dbo.StudentAchieve
SELECT sum(Math+Chinese) AS total FROM dbo.StudentAchieve
10.2 聚集不同值
以上5個聚集函數都可以如下使用:
-
- 對所有得行執行計算,指定ALL參數或不給參數。
- 值包含不同的值,指定DISTINCT參數
SELECT AVG(distinct Math) AS math_avg FROM dbo.StudentAchieve
10.3 組合聚集函數
SELECT COUNT(*) as num_count,MIN(Math) AS min_math,MAX(Math) AS max_math FROM dbo.StudentAchieve
第十一章 分組數據
11.1 數據分組
SELECT COUNT(*) AS math_95 FROM dbo.StudentAchieve WHERE Math>95
11.2 創建分組
SELECT StudentID,COUNT(*) AS column1 FROM dbo.StudentAchieve GROUP BY StudentID
在具體使用GROUP BY子句前,需要知道一些重要的規定:
-
- GROUP BY子句可以包含任意數目的列。這使得能對分組進行嵌套,為數據分組提供更細緻的控制。
- 如果在GROUP BY子句中快安了分組,數據將在最後規定的分組上進行彙總。換句話說,在建立分組時指定的所有列都一起計算(所以不能從個別的列取回數據)。
- GROUP BY子句中列出的每個列都必須是檢索列或有效的表達式(但不能是聚集函數)。如果在SELECT中使用表達式,則必須在GROUP BY子句中指定相同的表達式。不能使用別名。
- 大多數SQL實現不允許GROUP BY列帶有長度可變的數據類型(如文本或備註型欄位)。
- 除聚集計算語句外,SELECT語句中的每個列都必須在GROUP BY子句中給出。
- 如果分組列中具有NULL值,則NULL將作為一個分組返回。如果列中有多行NULL值,它們將分為一組
- GROUP BY子句必須出現在WHERE子句之後,ORDER BY子向之前。
11.3 過濾分組
SELECT StudentID,COUNT(*) AS column1 FROM dbo.StudentAchieve GROUP BY StudentID HAVING COUNT(*)=2
11.4 分組和排序
ORDER BY與GROUP BY
ORDER BY |
GROUP BY |
排序產生的輸出 任意列都可以使用(甚至非選擇的列也可以使用) 不一定需要 |
分組行。但輸出可能不是分組的順序 只可能使用選擇列或表達式列,而且必須使用每個選擇列表達式 如果與聚集函數一起使用列(或表達式),則必須使用 |
11.5 SELECT子句順序
子句 |
說明 |
是否必須使用 |
SELECT |
要返回的列或表達式 |
是 |
FROM |
從中檢索數據的表 |
僅在從表選擇數據時使用 |
WHERE |
行級過濾 |
否 |
GROUP BY |
分組說明 |
僅在按組計算聚集時使用 |
HAVING |
組級說明 |
否 |
ORDER BY |
輸出排序順序 |
否 |
第十二章 使用子查詢
12.1 子查詢
查詢(query)任何SQL語句都是查詢。
SQL還允許創建子查詢(subquery),即:嵌套在其他查詢中的查詢。
12.2 利用子查詢進行過濾
SELECT StudentName FROM dbo.StudentInfo WHERE StudentID IN ( SELECT StudentID FROM dbo.StudentAchieve WHERE Math > 95 );
12.3 作為計算欄位使用子查詢
SELECT StudentID,( SELECT COUNT(*)FROM dbo.StudentAchieve WHERE StudentID = StudentID) AS column1 FROM dbo.StudentInfo;
第十三章 聯結表
13.1 聯結
可伸縮性(scale)能夠適應不斷增加的工作量而不失敗。設計良好的資料庫或應用程式稱之為可伸縮性好、
13.2 創建聯結
SELECT StudentName,Math, Chinese FROM dbo.StudentInfo,dbo.StudentAchieve WHERE StudentAchieve.StudentID = StudentInfo.StudentID;
13.2.1 WHERE子句的重要性
笛卡兒積(cartesian product)由沒有聯結條件的表關係返回的結果為笛卡兒積。檢索出的行的數目將是第一個表中的行數乘以第二個表中的行數。
SELECT StudentName,Math,Chinese FROM dbo.StudentInfo,dbo.StudentAchieve
13.2.2 內部聯結
SELECT StudentName, Math,Chinese FROM dbo.StudentInfo INNER join dbo.StudentAchieve ON StudentAchieve.StudentID = StudentInfo.StudentID
13.2.3 聯結多個表
SELECT StudentName,Math,Chinese, Grade FROM dbo.StudentInfo,dbo.StudentAchieve, dbo.ClassInfo WHERE StudentInfo.StudentID = StudentAchieve.StudentID AND ClassInfo.StudentID = StudentAchieve.StudentID AND Math > 90;
第十四章 創建高級聯結
14.1 使用表別名
SELECT StudentName,Math, Chinese,Grade FROM dbo.StudentInfo AS a, dbo.StudentAchieve AS b, dbo.ClassInfo AS c WHERE a.StudentID = b.StudentID AND c.StudentID = a.StudentID AND Math > 90;
14.2 使用不同類型的聯結
14.2.1 自聯結
SELECT StudentID,StudentName,Gender FROM dbo.StudentInfo WHERE Gender =( SELECT Gender FROM dbo.StudentInfo WHERE StudentID = 's00001')
SELECT a.StudentID,a.StudentName,a.Gender FROM dbo.StudentInfo AS a,dbo.StudentInfo AS b WHERE a.Gender = b.Gender AND b.StudentID = 's00001';
14.2.2 自然聯結
SELECT StudentName,Math, Chinese,Grade FROM dbo.StudentInfo AS a, dbo.StudentAchieve AS b, dbo.ClassInfo AS c WHERE a.StudentID = b.StudentID AND c.StudentID = a.StudentID AND Math > 90;
14.2.3 外部聯結
SELECT StudentName,Gender,Math,Chinese FROM dbo.StudentInfo LEFT JOIN dbo.StudentAchieve ON StudentAchieve.StudentID = StudentInfo.StudentID;
SELECT StudentName,Gender,Math,Chinese FROM dbo.StudentInfo RIGHT JOIN dbo.StudentAchieve ON StudentAchieve.StudentID = StudentInfo.StudentID;
14.3 使用帶聚集函數的聯結
SELECT Grade,COUNT(Age) AS age_count,Age FROM dbo.StudentInfo INNER JOIN dbo.ClassInfo ON ClassInfo.StudentID = StudentInfo.StudentID GROUP BY ClassInfo.Grade,Age
14.4 使用聯結和聯結條件
-
- 註意所使用的聯結類型。一般我們使用內部聯結,但使用外部聯結也是有效的。
- 關於確切的聯結語法,應該查看具體的文檔,看相應的DBMS支持何種語法(大多數DBMS使用這兩章中描述的某種語法形式)。
- 保證使用正確的聯結條件(不管是採用哪種語法),否則將返回不正確的數據。
- 應該總是提供聯結條件,否則會得出笛卡兒積。
- 在一個聯結中可以包含多個表,甚至對於每個聯結可以採用不同的聯結類型。雖然這樣做是合法的,一般也很有用,但應該在起測試它們前,分別測試每個聯結。這將使故障排除更為簡單。
第十五章 組合查詢
15.1 組合查詢
SQL允許執行多個查詢,並將結果作為單個查詢結果集返回。這些組合查詢通常稱為並(union)或複合查詢(compound query)。
15.2 創建組合查詢
15.2.1 使用UNION
SELECT StudentID,StudentName,Age,Gender FROM dbo.StudentInfo WHERE Age=5 UNION SELECT StudentID,StudentName,Age,Gender FROM dbo.StudentInfo WHERE Gender='男'
SELECT StudentID,StudentName,Age,Gender FROM dbo.StudentInfo WHERE Age=5 OR Gender='男'
15.2.2 UNION規則
-
- UNION必須由兩條或兩條以上的SELECT語句組成,語句之間用關鍵宇UNION分隔(因此,如果組合4條SELECT語句,將要使用3個UNION關鍵宇)。
- UNION中的每個查詢必須包含相同的列、表達式或聚集西數(不過各個列不需要以相同的次序列出)。
- 列數據類型必須相容:類型不必完全相同,但必須是DBMS可以隱含地轉換的類型(例如,不同的數值類型或不同的日期類型)。
15.2.3 包含或取消重覆的行
SELECT StudentID,StudentName,Age,Gender FROM dbo.StudentInfo WHERE Age=5 UNION ALL SELECT StudentID,StudentName,Age,Gender FROM dbo.StudentInfo WHERE Gender='男'
15.2.4 對組合查詢結果排序
SELECT StudentID,StudentName,Age,Gender FROM dbo.StudentInfo WHERE Age=5 UNION SELECT StudentID,StudentName,Age,Gender FROM dbo.StudentInfo WHERE Gender='男' ORDER BY Gender
第十六章 插入數據
16.1 數據插入
16.1.1 插入完整的行
INSERT INTO dbo.StudentInfo VALUES( 's00010