引言
SQL(Structured Query Language,結(jié)構(gòu)化查詢語言)可以用于數(shù)據(jù)庫創(chuàng)建和數(shù)據(jù)庫查詢,實現(xiàn)數(shù)據(jù)庫結(jié)構(gòu)的增刪改查和數(shù)據(jù)庫記錄的增刪改查。
命令綜述
SQL命令根據(jù)功能可以分為四個種類:
- 數(shù)據(jù)定義語言(Data Definition Language,DDL)
- 數(shù)據(jù)操縱語言(Data Manipulation Language,DML)
- 數(shù)據(jù)控制語言(Data Control Language,DCL)
- 事務(wù)控制語言(Transaction Control Language,TCL)
數(shù)據(jù)定義語言(DDL)
DDL用于創(chuàng)建和修改數(shù)據(jù)庫結(jié)構(gòu)。
DDL的目的在于實現(xiàn)關(guān)系模式(以及一些額外結(jié)構(gòu),如索引等約束),并得到一個實際的關(guān)系數(shù)據(jù)庫。
常用的命令有:CREATE、ALTER、DROP
數(shù)據(jù)操縱語言(DML)
DML用于操作數(shù)據(jù)庫中的數(shù)據(jù),包括對數(shù)據(jù)的插入、修改、刪除及檢索等操作。
在數(shù)據(jù)庫的生命周期中,允許有新數(shù)據(jù)的插入,并允許已有數(shù)據(jù)的修改和刪除。
常用命令有:INSERT INTO、UPDATE、DELETE、SELECT
數(shù)據(jù)控制語言(DCL)和事務(wù)控制語言(TCL)
DCL和TCL語句可用于與數(shù)據(jù)庫維護及管理相關(guān)的多種過程。
DCL命令幫助實現(xiàn)數(shù)據(jù)的存取控制。
TCL用于數(shù)據(jù)庫中的事務(wù)管理。
SQL數(shù)據(jù)類型
| 數(shù)據(jù)類型 | 釋義 |
|---|---|
| CHAR(n) | n個字符的固定長度字符串 |
| VARCHAR(n) | 最大長度為n個字符的可變長度字符串 |
| INT | 整型 |
| NUMERIC(x,y) | x位數(shù)字,小數(shù)點后的位數(shù)為y |
| DATE | 日期值(年,月,日) |
SQL語法簡要說明
-
分號
緊跟在每一條SQL語句后面,表示一個SQL命令的結(jié)束。一系列SQL語句里,分號表示每條SQL語句何時結(jié)束。 -
SQL關(guān)鍵字
即SQL命令中所使用的表和列的名字,不區(qū)分大小寫。
考慮到可讀性,SQL關(guān)鍵字通常使用大寫,表名和列名使用小寫。
CREATE TABLE
SQL命令CREATE TABLE用于關(guān)系表的創(chuàng)建和連接。
使用方法:
CREATE TABLE <表名> ( 列名 數(shù)據(jù)類型 [列約束] ,...,[PRIMARY KEY (主碼列,...)] [REFERENCES 表名(外碼列)])
圓括號中的后半部分是關(guān)系表的描述。
下面介紹具體用法:
// 單主碼列
CREATE TABLE team (
team_id INT NOT NULL,
team_name VARCHAR(20) NOT NULL,
PRIMARY KEY (team_id)
);
// 單一外鍵
CREATE TABLE player (
player_id INT NOT NULL,
player_name VARCHAR(15) NOT NULL,
rank INT,
career_start_date DATE NOT NULL,
PRIMARY KEY (player_id),
FOREIGN KEY (team_id) REFERENCES team(team_id),
// FOREIGN KEY (team_id) REFERENCES team 后面表的主碼可以被省略
);
// 復(fù)合主碼,多個外鍵
CREATE TABLE solo_point (
team_id INT NOT NULL,
player_id INT NOT NULL,
point INT NOT NULL,
PRIMARY KEY (team_id, player_id),
FOREIGN KEY (team_id) REFERENCES team,
FOREIGN KEY (player_id) REFERENCES player
);
DROP TABLE
命令DROP TABLE用于從數(shù)據(jù)庫移除關(guān)系表
DROP TABLE team
當(dāng)關(guān)系表中存在依賴關(guān)系時,不能優(yōu)先刪除被依賴的關(guān)系表,要按照順序,從最外層開始刪除。
INSERT INTO
INSERT INTO語句用于向已創(chuàng)建好的關(guān)系表中填入數(shù)據(jù)
INSERT INTO <tablename> VALUES(value1,value2,...)
value按照順序?qū)?yīng)table中的列
如果想僅插入table表中的指定列,可以按照下面的寫法:
INSERT INTO <tablename>(col1,col3,col5,...) VALUES(value1,value3,value5,...)
SELECT
SELECT語句用于從數(shù)據(jù)庫關(guān)系中檢索數(shù)據(jù),是最常用的SQL語句
//檢索player表中的所有內(nèi)容 * 號代表所有列
SELECT * FROM player;
// 檢索player表中的player_id和player_name列
SELECT player_id,player_name FROM player;
// 檢索派生屬性
SELECT rank * 10 FROM player
SELECT還可以與一下關(guān)鍵字組合使用:WHERE、GROUP BY、HAVING、ORDER BY等
WHERE
SELECT語句可以包含WHERE條件,WHERE條件決定了應(yīng)該檢索哪些列、不檢索哪些列
- 基礎(chǔ)用法
//檢索天梯積分大于8000的選手
SELECT * FROM player WHERE rank > 8000;
// = 等于
// < 小于
// > 大于
// <= 小于等于
// >= 大于等于
// != 不等于
// <> 不等于(可選標(biāo)識)
- 一個WHERE子句中可以使用多個比較表達式,用布爾型邏輯操作符AND或OR進行連接
// 檢索1隊中積分大于8000的選手
SELECT * FROM player WHERE team_id = 1 AND rank > 8000;
// 檢索所有選手中名叫“張三”和“李四”的
SELECT * FROM player WHERE player_name = '張三' OR player_name = '李四';
DISTINCT
DISTINCT關(guān)鍵字的作用是在SELECT語句執(zhí)行后隊結(jié)果進行去重
// 檢索所有選手所在的省份
SELECT DISTINCT province FROM player;
ORDER BY
ORDER BY關(guān)鍵字的作用是對SELECT查詢結(jié)果的某一列或多個列進行排序
// 對所有選手的rank積分進行排序 默認(rèn)為升序排列
SELECT * FROM player ORDER BY rank;
// 降序排列
SELECT * FROM player ORDER BY rank DESC;
// 對多列排序 對積分降序 對年齡升序
SELECT * FROM player ORDER BY rank DESC,age;
LIKE
在WHERE子句中使用LIKE關(guān)鍵字檢索某列的值與給定的條件匹配的記錄
// %是一個通配符,表示一個空串或任意字符串
// 檢索所有李姓選手 李為第一個字符 后面為任意字符%
SELECT * FROM player WHERE name LIKE '李%';
// _是另一個通配符,表示任意的一個字符
// 檢索所有李姓單名的選手
SELECT * FROM player WHERE name LIKE '李_';
聚合函數(shù)
為了計算和統(tǒng)計查詢結(jié)果,SQL提供了如下幾個聚合函數(shù)(aggregate functions):COUNT、SUM、AVG、MIN以及MAX
// 統(tǒng)計所有選手的數(shù)量
SELECT COUNT(*) FROM player;
// 統(tǒng)計1隊中所有選手獲得的MVP總數(shù)
SELECT SUM(mvp) FROM player WHERE team_id = 1;
// 統(tǒng)計1隊中所有選手rank平均分
SELECT AVG(rank) FROM player WHERE team_id = 1;
// 檢索1隊中rank分最低的選手的分?jǐn)?shù)
SELECT MIN(rank) FROM player WHERE team_id = 1;
// 檢索1隊中rank分最高的選手的分?jǐn)?shù)
SELECT MAX(rank) FROM player WHERE team_id = 1;
COUNT函數(shù)可以用*也可以指定列名,通常情況下檢索結(jié)果是相同的。當(dāng)指定列名中存在空值時,指定列名會跳過該記錄,而*不會,此時會得到不同的統(tǒng)計結(jié)果。
GROUP BY
聚合函數(shù)通常和GROUP BY關(guān)鍵字一起使用,這樣就可以實現(xiàn)對組的聚合操作,組是一系列相關(guān)聯(lián)的數(shù)據(jù)記錄構(gòu)成的集合
// 統(tǒng)計每個隊伍的mvp總數(shù)以及rank平均分
SELECT team_id, SUM(mvp), AVG(rank) FROM player GROUP BY team_id;
// 還可以對多個列同時進行分組
SELECT team_id, SUM(mvp), AVG(rank) FROM player GROUP BY team_id, sex;
HAVING
HAVING子句決定GROUP BY的查詢結(jié)果哪些展示哪些不展示,HAVING子句必須同時包含GROUP BY子句
// 查詢隊伍的mvp總數(shù)大于等于10個且rank平均分在7000之上的隊伍
SELECT team_id, SUM(mvp), AVG(rank) FROM player GROUP BY team_id HAVING SUM(mvp) >= 10 AND AVG(rank) > 7000;
嵌套查詢
嵌套查詢也稱為內(nèi)部查詢,包含了嵌套查詢的查詢稱為外部查詢
// 查詢1隊中rank分?jǐn)?shù)低于平均值的選手
SELECT * FROM player WHERE team_id = 1 AND rank < (SELECT AVG(rank) FROM player);
IN
IN關(guān)鍵字用于單個值與多個值組合而成的集合之間的比較
// 查詢rank分?jǐn)?shù)為7000、7500、8000整的玩家
SELECT * FROM player WHERE rank IN (7000,7500,8000);
// 查詢隊伍冠軍數(shù)量大于5個的所有選手
SELECT * FROM player WHERE team_id IN(SELECT team_id FROM team WHERE champion > 5)
JOIN
使用JOIN操作符可以實現(xiàn)多個表的查詢
// 查詢所有選手的姓名以及隊名
// 相同的列名需要用 表名.列名 區(qū)分
SELECT player.name, team.name FROM player, team WHERE player.team_id = team.team_id;
WHERE player.team_id = team.team_id 是一個JOIN條件,若沒有JOIN條件,得出的結(jié)果是兩個結(jié)果的笛卡爾積,將會有m x n行結(jié)果。
別名
查詢中任何地方都可以使用短的別名來替代長的關(guān)系名
// 用別名重命名表的名稱
SELECT p.name, t.name FROM player p, team t WHERE p.team_id = t.team_id;
// 用別名重命名列的名稱
SELECT p.name pname, t.name tname FROM player p, team t WHERE p.team_id = t.team_id;
// 同使用AS關(guān)鍵字
SELECT p.name AS pname, t.name AS tname FROM player p, team t WHERE p.team_id = t.team_id;
注意:WHERE子句中的列名不能使用別名
多關(guān)系連接
一個查詢可以包含多個JOIN來連接多個關(guān)系
ALTER TABLE
ALTER TABLE命令用于修改已創(chuàng)建的關(guān)系結(jié)構(gòu)
// 增加一列 位置
ALTER TABLE player ADD(position varchar(10));
// 刪除一列 位置
// ALTER TABLE player DROP(position);
UPDATE
SQL中UPDATE命令用于修改存于數(shù)據(jù)關(guān)系中大數(shù)據(jù)
// 修改1隊隊名為FGNB
UPDATE team SET team_name = 'FGNB' WHERE team_id = 1;
DELETE
SQL中DELETE命令用于刪除數(shù)據(jù)庫關(guān)系中隊數(shù)據(jù)
// 刪除姓名叫 李二狗 的隊員數(shù)據(jù)
DELETE FROM player WHERE player_name = '李二狗';
CREATE VIEW 和 DROP VIEW
視圖(View)是SQL中的一種機制,該機制允許查詢的結(jié)構(gòu)保存在RDBMS中。視圖也稱為虛表,因為它沒有任何的物理存儲的數(shù)據(jù)。
// 使用方法
CREATE VIEW view_name_a SELECT ...
// 也可以和實表一樣執(zhí)行查詢操作
SELECT * FROM view_name_a;
// 移除視圖
DROP VIEW view_name_a;
集合運算
SQL同樣支持標(biāo)準(zhǔn)的集合運算(set operator):并運算(UNION)、交運算(INTERSECT)和差運算(EXCEPT/MINUS)。集合運算用于合并兩條或多條能相容的查詢結(jié)果。
定義兩個集合相容,要求這兩個集合列的數(shù)目相同,且每個列的數(shù)據(jù)類型相匹配。
使用方法:
SELECT A UNION SELECT B;
SELECT A INTERSECT SELECT B;
SELECT A MINUS SELECT B;
關(guān)系與自身的連接(自連接)
若一個關(guān)系有一個外碼參照其本身的主碼,則在查詢中這個關(guān)系就可以和它自己建立連接。這樣的連接也稱為自連接(SELF-JOIN)。
OUTER JOIN
當(dāng)一個關(guān)系外碼的值和另一個關(guān)系主碼的值相匹配時,JOIN運算能合并這兩個關(guān)系記錄。
OUTER JOIN (外連接)語句是JOIN(連接)的變體操作,它將保留那些在連接中不能匹配的記錄。
有三種形式的外連接:LEFT OUTER JOIN(左外連接)、RIGHT OUTER JOIN(右外連接)和FULL OUTER JOIN(全外連接)。
左外連接
對左外連接來說,所有出現(xiàn)在左外連接運算之前(左邊)關(guān)系中的記錄都會被保留在查詢結(jié)果中,包括那些沒能滿足匹配條件的記錄。若關(guān)系中的記錄以這種方式與其他關(guān)系的記錄建立連接,那些不能匹配的記錄將會被設(shè)為空值。右外連接
對于右外連接來說,所有出現(xiàn)在有外連接運算之后(右邊)關(guān)系中的記錄都會被保留在查詢結(jié)果中,包括那些沒能滿足匹配條件的記錄,并用空值表示。全外連接
對于全外連接來說,即使兩個關(guān)系沒有相匹配的記錄,其所有記錄也都會保留在查詢結(jié)果里。
IS NULL
在某一查詢中,包含某一列的值與空值相比較時,就需要在WHERE語句中使用IS NULL。
EXISTS
在查詢的內(nèi)查詢(嵌套查詢)中,若使用了外查詢SELECT部分列出的某關(guān)系的某列或某些列,則將這個內(nèi)查詢稱為相關(guān)子查詢。這種情況下,EXISTS操作就可以用來測試內(nèi)查詢的結(jié)果是否為空。
SELECT * FROM table1 t1 WHERE EXISTS (SELECT * FROM table2 t2 WHERE t1.id = t2.id)
NOT
NOT操作配合條件比較使用,返回布爾值TRUE或FALSE。