數(shù)據(jù)庫-SQL

引言

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。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容