臨時抱佛腳學SQL,在這邊做一些整理。部分實例摘抄自W3School.由於是有PYTHON pandas的基礎上看SQL,感覺兩者衚衕的地方是很多的。
1 基本結構
可以把 SQL 分爲兩個部分:數據操作語言 (DML) 和 數據定義語言 (DDL)。
SQL (結構化查詢語言)是用於執行查詢的語法。但是 SQL 語言也包含用於更新、插入和刪除記錄的語法。查詢和更新指令構成了 SQL 的 DML 部分:
- SELECT - 從數據庫表中獲取數據
- UPDATE - 更新數據庫表中的數據
- DELETE - 從數據庫表中刪除數據
- INSERT INTO - 向數據庫表中插入數據
SQL 的數據定義語言 (DDL) 部分使我們有能力創建或刪除表格。我們也可以定義索引(鍵),規定表之間的鏈接,以及施加表間的約束。SQL 中最重要的 DDL 語句:
- CREATE DATABASE - 創建新數據庫
- ALTER DATABASE - 修改數據庫
- CREATE TABLE - 創建新表
- ALTER TABLE - 變更(改變)數據庫表
- DROP TABLE - 刪除表
- CREATE INDEX - 創建索引(搜索鍵)
- DROP INDEX - 刪除索引
NOTE:SQL 對大小寫不敏感!
2 基本SQL語句
2.1 SELECT語句
SELECT 列名稱 FROM 表名稱
2.2 SELECT DISTINCT語句
找出表中唯一不同的值並返回。
SELECT DISTINCT 列名稱 FROM 表名稱
2.3 SQL WHERE
WHERE有條件地從表中取出數據。
SELECT 列名稱 FROM 表名稱 WHERE 列 運算符 值
操作符 | 描述 |
---|---|
= | 等於 |
<> | 不等於 |
> | 大於 |
< | 小於 |
>= | 大於等於 |
<= | 小於等於 |
BETWEEN | 在某個範圍內 |
LIKE | 搜索某種模式 |
NOTE:SQL 使用單引號來環繞文本值(大部分數據庫系統也接受雙引號)。如果是數值,請不要使用引號。
2.3.1 LIKE操作符
SELECT column_name(s)
FROM table_name
WHERE column_name LIKE pattern
在搜索數據庫中的數據時,SQL 通配符可以替代一個或多個字符。在 SQL 中,可使用以下通配符:
通配符 | 描述 |
---|---|
% | 替代一個或多個字符 |
_ | 僅替代一個字符 |
[charlist] | 字符列中的任何單一字符 |
[^charlist]或者[!charlist] |
不在字符列中的任何單一字符 |
% NOTES:(_相似)
- pattern中以xx開始:LIKE 'xx%'
- 以xx結束:LIKE '%xx'
- 帶有xx:LIKE '%xx%'
- 不帶xx:NOT LIKE '%xx%'
例:表Person
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
2 | Bush | George | Fifth Avenue | New York |
3 | Carter | Thomas | Changan Street | Beijing |
從 "Persons" 表中選取居住在包含 "lon" 的城市裏的人:
SELECT * FROM Persons
WHERE City LIKE '%lon%'
從 "Persons" 表中選取居住在不包含 "lon" 的城市裏的人:
SELECT * FROM Persons
WHERE City NOT LIKE '%lon%'
[charlist] 通配符:
例:
從 "Persons" 表中選取居住的城市以 "A" 或 "L" 或 "N" 開頭的人:
SELECT * FROM Persons
WHERE City LIKE '[ALN]%'
結果:
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
2 | Bush | George | Fifth Avenue | New York |
2.3.2 IN操作符
IN 操作符允許我們在 WHERE 子句中規定多個值。
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...)
2.3.3 BETWEEN操作符
操作符 BETWEEN ... AND 會選取介於兩個值之間的數據範圍。這些值可以是數值、文本或者日期。
SELECT column_name(s)
FROM table_name
WHERE column_name
BETWEEN value1 AND value2
NOTE:不同的數據庫對 BETWEEN...AND 操作符的處理方式是有差異的。某些數據庫會列出介於 VALUE1 和 VALUE2 之間的人,但不包括 VALUE1 和 VALUE2 ;某些數據庫會列出介於 VALUE1 和 VALUE2之間幷包括 VALUE1和VALUE2的人;而另一些數據庫會列出介於 VALUE1 和 VALUE2之間的人,包括 VALUE1 ,但不包括VALUE2。所以,需要數據庫是如何處理 BETWEEN....AND 操作符的!
2.4 AND$OR運算符
如果第一個條件和第二個條件都成立,則 AND 運算符顯示一條記錄。
如果第一個條件和第二個條件中只要有一個成立,則 OR 運算符顯示一條記錄。
例:表Person如下
執行語句:
SELECT * FROM Persons WHERE (FirstName='Thomas' OR FirstName='William')
AND LastName='Carter'
結果:
LastName | FirstName | Address | City |
---|---|---|---|
Carter | Thomas | Changan Street | Beijing |
Carter | William | Xuanwumen10 | Beijing |
2.5 ORDER BY子句
ORDER BY 語句用於根據指定的列對結果集進行排序,默認按照升序對記錄進行排序。如果希望按照降序對記錄進行排序,可以使用 DESC 關鍵字。
例:表Orders
Company | OrderNumber |
---|---|
IBM | 3532 |
W3School | 2356 |
Apple | 4698 |
W3School | 6953 |
執行語句:
SELECT Company, OrderNumber FROM Orders ORDER BY Company DESC, OrderNumber ASC
結果:
Company | OrderNumber |
---|---|
W3School | 2356 |
W3School | 6953 |
IBM | 3532 |
Apple | 4698 |
2.6 INSERT INTO語句(表中插入數據)
INSERT INTO 表名稱 VALUES (值1, 值2,....)
也可以指定所要插入數據的列:
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
2.7 UPDATE語句(修改表中數據)
UPDATE 表名稱 SET 列名稱 = 新值 WHERE 列名稱 = 某值
修改若干列的例子:表Person
LastName | FirstName | Address | City |
---|---|---|---|
Gates | Bill | Xuanwumen 10 | Beijing |
Wilson | Champs-Elysees |
執行語句:
UPDATE Person SET FirstName='Fred',Address = 'Zhongshan 23', City = 'Nanjing'
WHERE LastName = 'Wilson'
結果:
LastName | FirstName | Address | City |
---|---|---|---|
Gates | Bill | Xuanwumen 10 | Beijing |
Wilson | Fred | Zhongshan23 | Nanjing |
2.8 DELETE語句(刪除表中的行)
DELETE FROM 表名稱 WHERE 列名稱 = 值
刪除所有行:
DELETE FROM 表名
或者
DELETE * FROM 表名
3 SQL高級用法
3.1 TOP子句
TOP 子句用於規定要返回的記錄的數目。
3.1.1 SQL Server 的語法
SELECT TOP number|percent column_name(s)
FROM table_name
3.1.2 MySQL 語法
SELECT column_name(s)
FROM table_name
LIMIT number
3.1.3 Oracle語法
SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number
3.2 SQL Alias(別名)
通過使用 SQL,可以爲列名稱和表名稱指定別名(Alias)。
表的 SQL Alias 語法:
SELECT column_name(s)
FROM table_name
AS alias_name
列的 SQL Alias 語法:
SELECT column_name AS alias_name
FROM table_name
例:假設我們有兩個表分別是:"Persons" 和 "Product_Orders"。我們分別爲它們指定別名 "p" 和 "po"。
現在,我們希望列出 "John Adams" 的所有定單。我們可以使用下面的 SELECT 語句:
SELECT po.OrderID, p.LastName, p.FirstName
FROM Persons AS p, Product_Orders AS po
WHERE p.LastName='Adams' AND p.FirstName='John'
3.3 SQL JOIN
SQL join 用於根據兩個或多個表中的列之間的關係,從這些表中查詢數據。這裏感覺和pandas的merge()功能高度相似。類比着理解可以輕鬆很多。
3.3.1 法一:通過主鍵
數據庫中的表可通過鍵將彼此聯繫起來。主鍵(Primary Key)是一個列,在這個列中的每一行的值都是唯一的。在表中,每個主鍵的值都是唯一的。這樣做的目的是在不重複每個表中的所有數據的情況下,把表間的數據交叉捆綁在一起。
例:表Person
Id_P | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
2 | Bush | George | Fifth Avenue | New York |
3 | Carter | Thomas | Changan Street | Beijing |
"Id_P" 列是 Persons 表中的的主鍵。這意味着沒有兩行能夠擁有相同的 Id_P。即使兩個人的姓名完全相同,Id_P 也可以區分他們。
表Orders
Id_O | OrderNo | Id_P |
---|---|---|
1 | 77895 | 3 |
2 | 44678 | 3 |
3 | 22456 | 1 |
4 | 24562 | 1 |
5 | 34764 | 65 |
"Id_O" 列是 Orders 表中的的主鍵,同時,"Orders" 表中的 "Id_P" 列用於引用 "Persons" 表中的人,而無需使用他們的確切姓名。"Id_P" 列把上面的兩個表聯繫了起來。
執行語句:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons, Orders
WHERE Persons.Id_P = Orders.Id_P
結果:
LastName | FirstName | OrderNo |
---|---|---|
Adams | John | 22456 |
Adams | John | 24562 |
Carter | Thomas | 77895 |
Carter | Thomas | 44678 |
3.3.2 法二:使用Join
如果我們希望列出所有人的定購,可以使用下面的 SELECT 語句:
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName
結果同上。
NOTE:INNER JOIN 與 JOIN 是相同的。
3.3.3 不同的 SQL JOIN
除了我們在上面的例子中使用的 INNER JOIN(內連接),我們還可以使用其他幾種連接。
下面列出了您可以使用的 JOIN 類型,以及它們之間的差異。這裏和pandas的merge()函數裏面,how='(inner/outer/left/right)'參數用法基本上是一致的。
- JOIN: 如果表中有至少一個匹配,則返回行
- LEFT JOIN: 即使右表中沒有匹配,也從左表返回所有的行
SELECT column_name(s)
FROM table_name1 --左連接的表,以它爲準
LEFT JOIN table_name2 --被連接的表
ON table_name1.column_name=table_name2.column_name
- RIGHT JOIN: 即使左表中沒有匹配,也從右表返回所有的行
- FULL JOIN: 只要其中一個表中存在匹配,就返回行
3.4 SQL UNION 和 UNION ALL 操作符
UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。
NOTE:UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同。
SQL UNION 語法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
NOTE:默認地,UNION 操作符選取不同的值。如果允許重複的值,請使用 UNION ALL。
SQL UNION ALL 語法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
3.5 SELECT INTO語句
SELECT INTO 語句從一個表中選取數據,然後把數據插入另一個表中,常用於創建表的備份復件或者用於對記錄進行存檔。
SELECT */column_name(s)
INTO new_table_name [IN externaldatabase]
FROM old_tablename
--後面可以接WHERE、JOIN等
3.6 CREATE語句
3.6.1 CREATE DATABASE 語句(創建數據庫)
CREATE DATABASE database_name
3.6.2 CREATE TABLE 語句(創建數據庫中的表)
CREATE TABLE 表名稱
(
列名稱1 數據類型,
列名稱2 數據類型,
列名稱3 數據類型,
....
)
數據類型 | 描述 |
---|---|
|
僅容納整數。在括號內規定數字的最大位數。 |
|
容納帶有小數的數字。 "size" 規定數字的最大位數。"d" 規定小數點右側的最大位數。 |
char(size) |
容納固定長度的字符串(可容納字母、數字以及特殊字符)。 在括號中規定字符串的長度。 |
varchar(size) |
容納可變長度的字符串(可容納字母、數字以及特殊的字符)。 在括號中規定字符串的最大長度。 |
date(yyyymmdd) | 容納日期。 |
- SQL約束
約束用於限制加入表的數據的類型。可以在創建表時規定約束(通過 CREATE TABLE 語句),或者在表創建之後也可以(通過 ALTER TABLE 語句)。
SQL約束主要包括以下幾種約束:
- NOT NULL:約束強制列不接受 NULL 值。
例:
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
- UNIQUE:約束唯一標識數據庫表中的每條記錄。UNIQUE 和 PRIMARY KEY 約束均爲列或列集合提供了唯一性的保證。PRIMARY KEY 擁有自動定義的 UNIQUE 約束。NOET:每個表可以有多個 UNIQUE 約束,但是每個表只能有一個 PRIMARY KEY 約束。
例:需要命名 UNIQUE 約束,以及爲多個列定義 UNIQUE 約束(MySQL / SQL Server / Oracle / MS Access:):
CREATE TABLE Persons
(
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
)
例:UNIQUE Constraint on ALTER TABLE
- 當表已被創建時,如需在 "Id_P" 列創建 UNIQUE 約束(MySQL / SQL Server / Oracle / MS Access:):
ALTER TABLE Persons
ADD UNIQUE (Id_P)
2.需命名 UNIQUE 約束,並定義多個列的 UNIQUE 約束(MySQL / SQL Server / Oracle / MS Access:):
ALTER TABLE Persons
ADD CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
例:撤銷UNIQUE 約束
MySQL:
ALTER TABLE Persons
DROP INDEX uc_PersonID
SQL Server / Oracle / MS Access:
ALTER TABLE Persons
DROP CONSTRAINT uc_PersonID
- PRIMARY KEY:PRIMARY KEY 約束唯一標識數據庫表中的每條記錄。主鍵必須包含唯一的值。主鍵列不能包含 NULL 值。每個表都應該有一個主鍵,並且每個表只能有一個主鍵。
- FOREIGN KEY:一個表中的 FOREIGN KEY 指向另一個表中的 PRIMARY KEY。FOREIGN KEY 約束用於預防破壞表之間連接的動作。FOREIGN KEY 約束也能防止非法數據插入外鍵列,因爲它必須是它指向的那個表中的值之一。
- CHECK:CHECK 約束用於限制列中的值的範圍。如果對單個列定義 CHECK 約束,那麼該列只允許特定的值。如果對一個表定義 CHECK 約束,那麼此約束會在特定的列中對值進行限制。
- DEFAULT:DEFAULT 約束用於向列中插入默認值。如果沒有規定其他的值,那麼會將默認值添加到所有的新記錄。
3.6.3 CREATE INDEX 語句
CREATE INDEX 語句用於在表中創建索引。在不讀取整個表的情況下,索引使數據庫應用程序可以更快地查找數據。
SQL CREATE INDEX 語法
CREATE INDEX index_name
ON table_name (column_name)
SQL CREATE UNIQUE INDEX 語法
CREATE UNIQUE INDEX index_name
ON table_name (column_name)
3.7 DROP語句
3.7.1 DROP TABLE語句(刪除表內數據)
DROP TABLE 表名稱
3.7.2 DROP DATABASE
DROP DATABASE 數據庫名稱
3.7.3 TRUNCATE TABLE 語句(刪除表內數據及表本身)
TRUNCATE TABLE 表名稱
3.7.4 DROP INDEX語句
不同數據庫用法不同。
3.8 ALTER TABLE語句
在表中添加列:
ALTER TABLE table_name
ADD column_name datatype
刪除表中的列:
ALTER TABLE table_name
DROP COLUMN column_name
改變表中列的數據類型:
ALTER TABLE table_name
ALTER COLUMN column_name datatype
3.9 AUTO INCREMENT 字段
Auto-increment 會在新記錄插入表中時生成一個唯一的數字。
3.10 CREATE VIEW語句
CREATE VIEW語句:
CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
更新視圖:
SQL CREATE OR REPLACE VIEW Syntax
CREATE OR REPLACE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
刪除視圖:
SQL DROP VIEW Syntax
DROP VIEW view_name
3.11 NULL
NOTE:
- 無法比較 NULL 和 0;它們是不等價的。
- 無法使用比較運算符來測試 NULL 值,比如 =, <, 或者 <>。
- 我們必須使用 IS NULL 和 IS NOT NULL 操作符。