一篇文章入門SQL語句
SQL
Structured Query Language,是專門用來查詢關係型資料庫的語言。也就是說不是關係型資料庫,就不能用SQL查詢了。
MySQL的主要學習,其實都是集中在SQL上的。另外一部分,才是資料庫的配置和速度優化。
SQL語句的分類:
DQL DML TPL DCL DDL CCL
語法結構
一些特點:
- SQL 不區分 大小寫
- 每句話以
;
結束 - 斷行、縮緊無需任何符號,直譯器在解釋時會把所有空符號都會合併為一個空格。
- 單行註釋採用
--
,多行註釋採用/* ... */
- 值的引號可以同時用
"
和',但是
"`相容性更強。 - 資料庫名、表名、列名,都可以用反引號`來包起來
SQL的語法,是將一條語句拆分成幾個組成部分:
-
Clauses
:主要命令,如 update/set/where -
Expressions
: 能產生值的語句,如"Jason"
,或age + 12
。 -
Predicates
: 條件判斷,即如果True則使用A值,否則B值。 -
Queries
: 即Select查詢讀取資料庫的語句。 -
Statements
: 即一整條以;
結尾的SQL語句
SQL Style 編寫風格
常用語句
伺服器查詢:
-- 顯示伺服器中所有的資料庫 show databases ; -- 進入一個數據庫 use 資料庫名 ; -- 顯示當前所在資料庫的資訊 select database() ; -- 顯示當前資料庫所有表名 (MySQL) show tables; -- 顯示指定資料庫所有表名 (MySQL) select table_name from information_schema.tables where table_schema='資料庫名' and table_type='base table'; -- 顯示指定表格的所有欄位名(MySQL) select column_name from information_schema.columns where table_schema='資料庫名' and table_name='表名'; -- 檢視某表結構 DESC 表名 ;
資料庫操作:
-- 建立一個數據庫 CREATE DATABASE 資料庫名 CHARSET=utf-8 ; -- 檢視資料庫的建立資訊 SHOW CREATE DATABASE 資料庫名 ; -- 刪除資料庫 DROP DATABASE 資料庫名 ; -- 或,用反引號包起來 DROP DATABASE `資料庫名`
資料表操作:
-- 顯示當前資料庫中的所有表 show tables ; -- 建立表 CREATE TABLE 表名 (欄位 型別 約束, 欄位 型別 約束, 欄位 型別 約束....) ; -- 如 CREATE TABLE staff ( id int primary key not null auto_increment, name varchar(30) ); -- 刪除表 DROP TABLE 表名 ; -- 查看錶的建立語句 SHOW CREATE TABLE 表名 ; -- 查看錶結構 DESC 表名 ; -- 修改表:新增一個欄位 ALTER TABLE 表名 ADD 欄位 型別 約束 ; -- 修改表:修改一個欄位 ALTER TABLE 表名 MODIFY 欄位 型別 約束 ; -- 修改表:刪除一個欄位 ALTER TABLE 表名 DROP 欄位 ; -- 新增一條記錄 INSERT INTO 表名 VALUES(欄位1, 欄位2, , 欄位4) ; --
CRUD 增刪改查
Create / Read / Update / Delete
查詢 SELECT
select查詢永遠是SQL中學習時間最長的。因為增刪改都是固定模式,語句也很簡單。但是查詢擁有極多的方式方法和關鍵字,能夠創造超多的組合搭配查詢,且每種查詢方式效率速度不一。所以SQL主要學的就是SELCT。
最簡單的select查詢:
SELECT filed1, field2, field3 FROM table_name ; SELECT filed1 AS age, field2 AS gender, field3 FROM table_name ; SELECT table_name.filed1, table_name.field2, table_name.field3 FROM table_name ; SELECT t.filed1, t.field2, t.field3 FROM table_name as t ; -- 刪除重複行 SELECT DISTINCT field1 FROM table_name ;
以下為各種Select語句的方式方法總結。
條件 WHERE
- 比較運算子:小於
<
, 大於>
, 小於等於<=
, 大於等於>=
, 等於=
, 不等於!=
或<>
- 邏輯運算子:
and
,or
,not
-
模糊查詢:
-
like
: 用%
替換1個字或多個字,_
替換1個字,word
包含指定的字word -
rlike
: 正則查詢,如^周.*$
-
- 範圍查詢:
field in (v1, v2, v3...)
,not in (...)
,between v1 and v2
,not between v1 and v2
- 空判斷:
field is null
,field is not null
SELECT filed1, field2 FROM table_name WHERE field3 > 10; ... WHERE field1 = "hello" AND field2 = "world" ; ... WHERE filed1 LIKE "Hel%" or filed2 LIKE "Hel__" ; ... WHERE field1 RLIKE "^He.*$" ; ... WHERE filed1 IN (12, 18, 19) and NOT IN (30, 40, 50) ; ... WHERE field1 BETWEEN 10 AND 20 and NOT BETWEEN 40 AND 50 ; ... WHERE filed1 IS NULL OR field3 IS NOT NULL ;
排序 ORDER BY
... WHERE ... ORDER BY age, gender ; ... WHERE ... ORDER BY age ASC ; ... WHERE ... ORDER BY age ASC, id DESC, gender ASC ;
內建聚合函式 FUNCTIONS
內建函式能夠處理一些很簡單的計算問題。
但是切記,查詢一個函式值時不要查詢其它欄位,除非使用GROUP分組等方法。
SELECT COUNT(*) FROM ... SELECT MAX(age) FROM ... SELECT SUM(age) FROM ... SELECT AVG(age) FROM ... SELECT ROUND( SUM(age)/COUNT(*), 2 ) FROM ... SELECT MAX(age) FROM ... -- 不允許:(因為邏輯不通,需要用到分組才行) -- SELECT name, age, ROUND( SUM(age)/COUNT(*), 2 ) FROM ...
分組 GROUP BY
SQL分組是一個比較容易混淆的概念。
SQL的分組是會完全破壞原先表結構的,然後生成一個 統計表
,純粹是為了數量統計用的。
分組GROUP單獨使用是沒什麼意義的,除非是和聚合函式Functions一起用。
分組的做法是:如果按gender分組,就只把gender一列取出來,做成一個unique的唯一gender列表,如 男; 女
,然後再建立一列,值對應的是每一種gender的記錄條數。
如果要檢視各組的其它資訊,需要用到特殊的函式 group_concat(filed1)
:
-- 報錯: -- SELECT name FROM ... GROUP BY gender ; -- SELECT * FROM ... GROUP BY gender ; -- 顯示gender的每種分組類別以及其下的記錄條數! SELECT gender, COUNT(*) FROM ... GROUP BY gender ; -- 顯示分組的平均 SELECT gender, AVG(*) FROM ... GROUP BY gender ; -- 顯示分組最大值 SELECT gender, MAX(*) FROM ... GROUP BY gender ; -- 顯示分組所包含的其它資訊 SELECT gender, GROUP_CONCAT(name) FROM ... GROUP BY gender ; SELECT gender, GROUP_CONCAT(name, "_", age) FROM ... GROUP BY gender ;
分組還有一個配合的關鍵字 having
,類似與where的篩選功能:
SELECT gender, COUNT(*) FROM ... GROUP BY gender HAVING COUNT(*) > 3 ;
分頁 LIMIT
-- 限制顯示結果的條數 SELECT ... FROM ... LIMIT 2 ; -- 分頁 格式為:LIMIT (第N頁-1)*每頁個數, 每頁個數 -- 第1頁,每頁2條 SELECT ... FROM ... LIMIT 0,2 ; -- 第2頁,每頁2條 SELECT ... FROM ... LIMIT 2,2 ; -- 第3頁,每頁2條 SELECT ... FROM ... LIMIT 4,2 ; -- 第4頁,每頁2條 SELECT ... FROM ... LIMIT 6,2 ;
連線 JOIN
SQL中的JOIN連線,實際上是用了數學上的 集合
概念。其中:
-
Inner Join
內連線: 相當於A and B
,代表兩個集合(表)的交集,即表中某欄位匹配上的條目。 -
Full Outer Join 全連線:相當於
A or B`,代表兩個表的並集,即兩表合併所有欄位和資料為一個表,未匹配的資料中的空欄位以null填充。 -
Right Join
右連線:使用left表裡所有資料,而right表中只保留匹配資料,且未匹配資料條目中的right表字段以null填充。 -
Left Join
左連線:使用right表裡所有資料,而left表中只保留匹配資料,且未匹配資料條目中的left表字段以null填充。
怎麼理解Left Join和Right Join?
首先,兩表匹配,各表都會有各自的 未匹配資料條目
。
那麼怎麼處理這些 未匹配資料
,就是這些左右的考量目標。
Left join,保留左表的未匹配資料。Right join,保留右表中的未匹配資料。Full join,保留所有未匹配資料。
那麼保留下的這些 未匹配資料
,肯定會有幾個來自 外面的欄位
是空的,這時候都統一以null填充。
另外,SQL連線兩表,不光要指定連線方式,還要指定 主鍵-外來鍵
的對應關係,使用 ON
關鍵字。
-- 內連線 SELECT ... FROM tb1 INNER JOIN tb2 ON tb1.key = tb2.id ; -- 左連線 SELECT ... FROM tb1 RIGHT JOIN tb2 ... -- 右連線 SELECT ... FROM tb1 LEFT JOIN tb2 ... -- 全連線 (MySQL不支援) SELECT ... FROM tb1 FULL OUTER JOIN tb2 ... -- 差集連線 (MySQL不支援) SELECT ... FROM tb1 FULL OUTER JOIN tb2 ON tb1.key = tb2.id WHERE tb1.key IS NULL OR tb2.id IS NULL;
自關聯
自連線,連線的兩個表都是 同一個表
,同樣可以由內連線,外連線各種組合方式,按實際應用去組合。
SELECT a.*, b.* FROM tb1 a, tb2 as b WHERE a.[name] = b.[name]
聯合 Union
UNION 操作符用於合併兩個或多個 SELECT 語句的 結果集
。
使用Union聯合的前提條件:
列
列出所有在中國和美國的不同的僱員名:
SELECT E_Name FROM Employees_China UNION SELECT E_Name FROM Employees_USA
UNION ALL
命令和 UNION
命令幾乎是等效的,不過 UNION ALL 命令會列出 所有的值
。
列出在中國和美國的所有的僱員:
SELECT E_Name FROM Employees_China UNION ALL SELECT E_Name FROM Employees_USA
子查詢
實際上就是用 ( select ...)
子語句返回一個值,來方便主句查詢。相當於bash指令碼中的 $(...)
功能。
SELECT ... FROM ... WHERE height = (SELECT MAX(height) FROM ...)