DQL高級查詢
多表查詢(關聯查詢、連接查詢)
1.笛卡爾積
emp表15條記錄,dept表4條記錄。
連接查詢的笛卡爾積為60條記錄。
2.內連接
不區分主從表,與連接順序無關。兩張表均滿足條件則出現結果集中。
--where子句 select * from emp,dept where emp.deptno = dept.deptno --inner join…on… select * from emp inner join dept on emp.deptno = dept.deptno --inner join…using… select * from emp INNER JOIN dept using(deptno)
3.自然連接
尋找兩表中字段名稱相等的字段進行連接,會自動去重重復列。
--自然連接(等值連接,表的字段名稱必須相同,去除重復行) select * from emp NATURAL JOIN dept;
4.外連接
有主從表之分,與連接順序有關。以驅動表為依據,匹配表依次進行查詢;匹配表中找不到數據,則以null填充。
--左外連接 left [outer] join .... ON... select * from emp left join dept on emp.deptno = dept.deptno;
5.自連接
同一個表里面的數據相關聯
--查詢所有的員工的姓名和上級領導的姓名 emp(內連接) select e1.ename ename ,e2.ename mgrname from emp e1,emp e2 where e1.mgr=e2.empno select e1.ename ename ,e2.ename mgrname from emp e1 left join emp e2 on e1.mgr=e2.empno
子查詢(嵌套查詢)
1.單行子查詢
子查詢的結果返回一行
select dname from dept where deptno = (select deptno from emp where empno=7788);
2.多行子查詢
查詢的結果返回一個集合
--查詢工資大於2000的員工的部門名稱 select dname from dept where deptno =any(select deptno from emp where sal > 2000); ANY ALL =ANY 含義就是in >any 大於最小值 <any 小於最大值 >all 大於最大值 <all 小於最小值
案例
--查詢大於所在部門的平均工資的員工信息。 --關聯查詢 1.分組每個部門平均工資 select * from emp e,(select deptno,avg(sal) avg from emp group by deptno) e1 where e.deptno = e1.deptno and e.sal > e1.avg --子查詢(主查詢可以將數據傳遞給子查詢) select * from emp e where sal > (select avg(sal) from emp e1 where e1.deptno = e.deptno) 1.先執行主查詢,將deptno傳給子查詢 2.子查詢拿到deptno,計算查詢的結果,返回給主查詢 3.主查詢拿到子查詢返回的結果執行查詢 --查詢薪水大於2000 emp 的部門名稱 dept select dname from dept where deptno in( select deptno from emp where sal > 2000); select dname from dept d where EXISTS( select * from emp e where sal > 2000 and d.deptno = e.deptno)
in和exists的區別
1.IN
主查詢的條件字段和子查詢返回字段必須一致。
先執行子查詢,將返回子查詢的結果給主查詢,再執行主查詢
2.EXISTS 主查詢不需要出現條件字段 先執行主查詢,將主查詢的表的字段傳給子查詢,如果在子查詢找到相應結果, 返回true,將該結果顯示在結果集中。否則返回false
聯合查詢
1.UNION
並集,所有的內容都查詢,重復的顯示一次
select * from emp where deptno = 20 union select * from emp where sal > 2000
2.UNION ALL
並集,所有的內容都顯示,包括重復的
事物
存儲引擎
Mysql的核心就是存儲引擎,DBMS借助於引擎實現增刪改查操作。
Mysql有多種存儲引擎,不同引擎在事務的支持,查詢的效率,索引策略等方面有不同。
InnoDB是事務型數據庫的首選,執行安全性數據庫,行鎖定和外鍵。mysql5.5之后默認使用。
MyISAM插入速度和查詢效率較高,但不支持事務。
MEMORY將表中的數據存儲在內存中,速度較快。
什么是事物
保證數據的一致性,一系列DML操作,要么同時成功,要么同時失敗。
事物的ACID特性
a) 原子性Atomicity: 一系列的DML操作不可分割。
b) 一致性Consistency:
數據一致性:事務執行前后整體的狀態不變。
約束:事務執行前后約束信息不變。
c) 隔離性(獨立性) Isolation:
並發事務是互相隔離的。
d) 持久性Durability:事務提交之后數據將持久化到數據庫。
事物的實現 tcl commit rollback
a) mysql數據庫默認是自動提交
set autocommit=0; 不自動提交
set autocomiit=1;自動提交
b) 手動開啟事務
start transaction/begin;
c) 手動提交或者回滾
commit;
rollback;
savepoint;保存點,恢復必須在事務提交之前。事務一旦提交,所有的保存點全部失效。
-- 關閉自動提交 set autocommit=0; -- 顯式開始事務 start TRANSACTION; -- DML update account set money = money - 20 where name = 'ls'; -- 保存點 -- SAVEPOINT a; delete from aa; update account set money = money + 20 where name = 'zs'; -- 提交 -- commit; -- 回滾 commit; -- 不起效 -- ROLLBACK to a;
注意:DDL操作會隱式事物提交
存儲程序
概念
存儲程序指的一組存儲和執行在數據庫服務器端的程序。
分類
1.存儲過程
2.存儲函數
3.觸發器
存儲過程
1.基本語法
CREATE PROCEDURE sel_emp(參數列表) BEGIN --操作 END;
2.使用
無參的存儲過程: CREATE PROCEDURE sel_emp() BEGIN select * from emp where deptno = 10; END; --存儲過程的調用 call sel_emp(); 有參的存儲過程: --根據部門編號查詢員工信息 CREATE PROCEDURE sel_emp2(dno int) BEGIN select * from emp where deptno=dno; END; --調用存儲過程 call sel_emp2(30); --根據員工編號查詢員工的名稱 CREATE PROCEDURE sel_emp3(eno int,OUT name varchar(20)) BEGIN select ename into name from emp where empno=eno; end; --調用 call sel_emp3(7788,@name); select @name; --根據員工編號查詢所在部門的編號 CREATE PROCEDURE sel_emp4(INOUT eno int) BEGIN select deptno into eno from emp where empno = eno; END; --調用 set @eno = 7788; call sel_emp4(@eno); select @eno; --分支語句 CREATE PROCEDURE cal_score(score int) BEGIN -- 聲明變量 DECLARE levels varchar(20); -- 分支 IF score >= 90 THEN -- 賦值 set levels = '優秀'; ELSEIF score >= 80 THEN set levels = '良好'; ELSE set levels = '不通過'; END IF; -- 輸出 select levels; END; --while循環 create PROCEDURE calc() BEGIN -- 聲明兩個變量 DECLARE sum int; DECLARE count int; -- 初始化 set sum = 0; set count = 1; -- 循環 while count <=100 DO set sum = sum + count; set count = count + 1; END WHILE; SELECT sum; END; --LOOP create PROCEDURE calc1() BEGIN -- 聲明兩個變量 DECLARE sum int; DECLARE count int; -- 初始化 set sum = 0; set count = 1; -- 循環 lip:LOOP set sum = sum + count; set count = count + 1; IF count > 100 THEN LEAVE lip; END IF; END LOOP; SELECT sum; END; call calc1(); create PROCEDURE calc3() BEGIN -- 聲明兩個變量 DECLARE sum int; DECLARE count int; -- 初始化 set sum = 0; set count = 1; -- 循環 REPEAT set sum = sum + count; set count = count + 1; UNTIL count > 100 END REPEAT; SELECT sum; END;
3.參數模式
in:外部傳進存儲過程
out:傳出
inout:傳進傳出
4.游標
--查詢所有員工的姓名 create PROCEDURE emp_cursor4() BEGIN DECLARE name varchar(20); DECLARE DONE boolean default 0; -- 聲明游標類型變量存儲所有員工的名稱 DECLARE emp_cursor CURSOR for select ename from emp; -- 結束設置狀態碼為1 DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET DONE = 1; -- 打開游標 open emp_cursor; -- 獲取游標中維護的值 lip:LOOP FETCH emp_cursor into name; IF DONE THEN leave lip; END IF; select name; END LOOP; -- 關閉游標 close emp_cursor; END;
存儲函數
--函數(確定的不變的 DETERMINISTIC Not ) create FUNCTION emp_func() RETURNS VARCHAR(20) DETERMINISTIC BEGIN DECLARE name varchar(20); select ename into name from emp where empno = 7788; RETURN name; END; select emp_func(); 函數有返回值 return 存儲過程可以單獨使用;但是函數只能作為語句的一部分。