Day3 MySql高級查詢


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
存儲過程可以單獨使用;但是函數只能作為語句的一部分。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM