前言
本篇主要介紹了數(shù)據(jù)庫中多表查詢以及事務(wù)相關(guān)的知識。
目錄
一、多表查詢
二、子查詢
三、事務(wù)
一、多表查詢
1.1 多表查詢的分類
多表查詢
- 內(nèi)連接
- 隱式內(nèi)連接
- 顯示內(nèi)連接
- 外連接
- 左外連接
- 右外連接
1.2 內(nèi)連接
內(nèi)連接的概念:
用左邊表的記錄去匹配右邊表的記錄,如果符合條件的則顯示
1.2.1 隱式內(nèi)連接
看不到 JOIN 關(guān)鍵字,條件使用 WHERE 指定
SELECT 字段名 FROM 左表, 右表 WHERE 條件
例如:
SELECT * FROM emp t1,dept t2 WHERE t1.`dept_id`= t2.`id`;
1.2.2 顯式內(nèi)連接
使用 INNER JOIN ... ON 語句, 可以省略 INNER
SELECT 字段名 FROM 左表 [INNER] JOIN 右表 ON 條件
例如:
SELECT * FROM emp t1 JOIN dept t2 ON t1.`dept_id`=t2.`id`;
1.3 外連接
1.3.1 左外連接
用左邊表的記錄去匹配右邊表的記錄(左表的記錄會全部顯示出來),如果符合條件的則顯示;
否則,顯示 NULL
可以理解為:
在內(nèi)連接的基礎(chǔ)上保證左表的數(shù)據(jù)全部顯示。
查詢的是左表所有數(shù)據(jù)以及其交集部分。
使用 LEFT OUTER JOIN ... ON,OUTER 可以省略
SELECT 字段名 FROM 左表 LEFT [OUTER] JOIN 右表 ON 條件
例如:
-- 使用左外連接查詢
-- 左外連接查詢能保證左表(dept )中的數(shù)據(jù)全部顯示出來
SELECT * FROM dept t1 LEFT JOIN emp t2 ON t1.`id`=t2.`dept_id`;
1.3.2 右外連接
用右邊表的記錄去匹配左邊表的記錄,如果符合條件的則顯示;
否則,顯示 NULL
可以理解為:
在內(nèi)連接的基礎(chǔ)上保證右表的數(shù)據(jù)全部顯示
使用 RIGHT OUTER JOIN ... ON,OUTER 可以省略
SELECT 字段名 FROM 左表 RIGHT [OUTER ]JOIN 右表 ON 條件
二、子查詢
2.1 子查詢的概念
- 一個查詢的結(jié)果做為另一個查詢的條件
- 有查詢的嵌套,內(nèi)部的查詢稱為子查詢
- 子查詢要使用括號
例如:
-- 查詢市場部中有哪些員
SELECT * FROM emp WHERE emp.dept_id=(SELECT id FROM dept WHERE dept.`name`='市場部');
2.2 子查詢結(jié)果的三種情況
2.2.1 子查詢的結(jié)果是單行單列
子查詢結(jié)果只要是單行單列,肯定在 WHERE 后面作為條件,
父查詢使用:比較運算符,如:> 、<、<>、= 等
SELECT 查詢字段 FROM 表 WHERE 字段=(子查詢);
例如:
-- 查詢工資最高的員工是誰
SELECT t1.`name`,t1.`salary` FROM emp t1 WHERE t1.`salary`=(SELECT MAX(salary) FROM emp);
--查詢工資小于平均工資的員工有哪些
SELECT t1.name ,t1.`salary` FROM emp t1 WHERE t1.`salary`<(SELECT AVG(salary) FROM emp);
2.2.2 子查詢的結(jié)果是多行單列
子查詢結(jié)果是單例多行,結(jié)果集類似于一個數(shù)組
父查詢使用 IN 運算符
SELECT 查詢字段 FROM 表 WHERE 字段 IN (子查詢);
例如:
--查詢工資大于 4000 的員工,來自于哪些部門的名字
SELECT t1.name FROM dept t1 WHERE t1.`id` IN (SELECT t2.dept_id FROM emp t2 WHERE t2.`salary`>4000);
-- 查詢開發(fā)部與財務(wù)部所有的員工信息
SELECT * FROM emp t1 WHERE t1.`dept_id` IN (SELECT t2.id FROM dept t2 WHERE t2.`name` IN ('開發(fā)部','財務(wù)部'));
2.2.3 子查詢的結(jié)果是多行多列
子查詢結(jié)果只要是多列,肯定在 FROM 后面作為表
子查詢作為表需要取別名,否則這張表沒有名稱則無法訪問表中的字段
例如:
-- 查詢出 2011 年以后入職的員工信息,包括部門名稱
SELECT * FROM dept t1, (SELECT * FROM emp WHERE join_date > '2011-1-1') t2 WHERE t2.dept_id = t1.id;
-- 也可以使用表連接
SELECT * FROM emp t1 JOIN dept t2 ON t1.`dept_id`=t2.`id` WHERE t1.`join_date`>'2011-1-1';
SELECT * FROM emp t1 JOIN dept t2 ON t1.`dept_id`=t2.`id` AND t1.`join_date`>'2011-1-1';
2.2.4 子查詢小結(jié)
- 子查詢結(jié)果只要是單列,則在 WHERE 后面作為條件
- 子查詢結(jié)果只要是多列,則在 FROM 后面作為表進行二次查詢
三、事務(wù)
3.1 什么是事務(wù)
在實際的開發(fā)過程中,一個業(yè)務(wù)操作如:轉(zhuǎn)賬,往往是要多次訪問數(shù)據(jù)庫才能完成的。
轉(zhuǎn)賬是一個用戶扣錢,另一個用戶加錢。如果其中有一條 SQL 語句出現(xiàn)異常,這條 SQL 就可能執(zhí)行失敗。
事務(wù)執(zhí)行是一個整體,所有的 SQL 語句都必須執(zhí)行成功。如果其中有 1 條 SQL 語句出現(xiàn)異常,則所有的SQL 語句都要回滾,整個業(yè)務(wù)執(zhí)行失敗。
MYSQL 中可以有兩種方式進行事務(wù)的操作:
- 手動提交事務(wù)
- 自動提交事務(wù)
3.2 手動提交事務(wù)
手動提交事務(wù)的 SQL 語句:
- start transaction :開啟事務(wù)
- commit :提交事務(wù)
- rollback :回滾事務(wù)
手動提交事務(wù)使用過程:
- 執(zhí)行成功的情況: 開啟事務(wù) -> 執(zhí)行多條 SQL 語句 -> 成功提交事務(wù)
- 執(zhí)行失敗的情況: 開啟事務(wù) -> 執(zhí)行多條 SQL 語句 -> 事務(wù)的回滾
如果事務(wù)中 SQL 語句沒有問題,commit 提交事務(wù),會對數(shù)據(jù)庫數(shù)據(jù)的數(shù)據(jù)進行改變。
如果事務(wù)中 SQL語句有問題,rollback 回滾事務(wù),會回退到開啟事務(wù)時的狀態(tài)。
3.3 自動提交事務(wù)
MySQL 默認每一條 DML(增刪改)語句都是一個單獨的事務(wù),每條語句都會自動開啟一個事務(wù),語句執(zhí)行完畢
自動提交事務(wù),MySQL 默認開始自動提交事務(wù)
3.4 事務(wù)原理
事務(wù)開啟之后, 所有的操作都會臨時保存到事務(wù)日志中, 事務(wù)日志只有在得到 commit 命令才會同步到數(shù)據(jù)表
中,其他任何情況都會清空事務(wù)日志(rollback,斷開連接)
3.5 事務(wù)的四大特征
- 原子性:是不可分割的最小操作單位,要么同時成功,要么同時失敗。
- 持久性:當事務(wù)提交或回滾后,數(shù)據(jù)庫會持久化的保存數(shù)據(jù)。
- 隔離性:多個事務(wù)之間。相互獨立。
- 一致性:事務(wù)操作前后,數(shù)據(jù)總量不變。
注:由于本人水平有限,所以難免會有理解偏差或者使用不正確的問題。如果小伙伴們有更好的理解或者發(fā)現(xiàn)有什么問題,歡迎留言批評指正~