1. 程式人生 > >MySQL:(二)

MySQL:(二)

必須 blank eache 條件 用戶名 所有 mgr mys lan

多表查詢-笛卡爾積

技術分享圖片

對於數據庫中 針對於兩張表的記錄數的所有記錄進行匹配,獲得笛卡爾積!??笛卡爾積結果是無效的,必須從笛卡爾積中選取有效的數據結果 !!!

-- 顯示結果就是笛卡爾積,兩個表記錄乘積
select * from emp,dept; 

內鏈接概念

  • 一般有效的數據 通常采用內鏈接的方式獲取有效數據
    select * from emp e,dept d where e.deptno = d.deptno;
  • 針對於內鏈接的語法,一般可以使用表別名進行查詢 也可以通過 join on 關鍵字進行鏈接
    -- join 用來鏈接兩張表,on 後添加兩張表需要鏈接的條件
    select * from emp join dept on emp.deptno = dept.deptno;

子查詢

  • 子查詢是嵌套在一個select語句中的另一個select語句。當需要從一個表中檢索信息,檢索條件值又是來自該表本身的內部數據時,子查詢非常有用;
  • 子查詢可以嵌入以下SQL子句中:where子句、having子句和from子句

單行子查詢

  內部select語句只返回一行結果的查詢(單列)

  • 主查詢的where子句使用單行子查詢返回結果要采用單行比較運算符(=、>、>=、<、<=、<>)
    --
    查詢工資比編號為7566雇員工資高的雇員姓名。 select ename from emp where sal> (select sal from emp where empno=7566) order by ename; -- 顯示和雇員scott同部門的雇員姓名、工資和部門編號。 select ename,sal,deptno from emp where deptno= (select deptno from emp where ename=SCOTT
    ); -- 顯示和雇員SCOTT從事相同工作,並且工資大於JAMES的雇員姓名、工作和工資 select ename,job,sal from emp where job= (select job from emp where ename=SCOTT) and sal> (select sal from emp where ename=JAMES);
    • 子查詢要用括號括起來;
    • 將子查詢放在比較運算符的右邊;
    • 不要在子查詢中使用order by子句,select語句中只能有一個order by子句,並且它只能是主select語句的最後一個子句

單行子查詢中使用組函數

-- 顯示工資最低的雇員姓名、工作和工資。
select ename,job,sal 
from emp 
where sal=(select min(sal) from emp);

having子句中使用單行子查詢

-- 顯示部門內最低工資比20部門最低工資要高的部門的編號及部門內最低工資。
-- 1、按部門顯示部門編號、部門最低工資
select deptno as 部門編號,
       min(sal) as 最低工資
from emp
group by deptno;

-- 2、查詢20部門最低工資
select min(sal) from emp where deptno=20;

-- 3、使用having子句把2作為1的子查詢
select deptno as 部門編號,
       min(sal) as 最低工資
from emp
group by deptno
having min(sal)>(select min(sal) 
                 from emp 
                 where deptno=20);

問題思考

  • 當單行子查詢返回的結果為null時,主查詢是否正確?
    -- 查詢和SMITH從事相同工作的雇員姓名和工作,如果SMITH誤拼寫成SMITHS則返回結果為null
    select ename,job
    from emp
    where job=(select job 
               from emp
               where ename=SMITHS);
  • 子查詢中使用group by子句,主查詢中是否可以使用單行比較符?
    -- 下面的SQL語句能正確執行嗎?
    select ename,job
    from emp
    where sal=(select min(sal)
               from emp
               group by deptno);

    ORA-01427: 單行子查詢返回多個行

from子句中使用子查詢

  在from子句中使用子查詢時,必須給子查詢指定別名。

-- 顯示工資高於部門平均工資的雇員姓名、工作、工資和部門號select ename,job,sal,emp.deptno 
from emp, (select deptno,avg(sal) avgsal
           from  emp
           group by deptno)s
where emp.deptno=s.deptno and sal>s.avgsal;

多表設計

E-R 圖的設計說明:

技術分享圖片

結論: 必須創建第三張關系表,在關系表中引用兩個實體主鍵作為外鍵

建表原則:創建的第三方關系表,將每張表的主鍵作為第三章表的聯合主鍵

多對多關系

案例演示說明: 老師和學員

圖解:

技術分享圖片

表設計:

技術分享圖片

--   多對多    老師 和學員 
create  table if not exists student(
id int primary key auto_increment,
name varchar(20)
);
create  table if not exists teacher(
id int primary key auto_increment,
name varchar(20)
);

-- 第三張 表  
create table if not exists student_teacher(
sid int,
tid int,
constraint student_teacher_student_fk foreign key (sid)  references student(id),
constraint student_teacher_teacher_fk foreign key (tid) references teacher(id),
primary key(sid,tid)
);

-- 蒼老師  李四  張三     題目 蒼老師有幾個學員  顯示學員信息  
insert  into  student values(null,李四);
insert  into  student values(null,張三);
insert  into  student values(null,王五);
insert  into  student values(null,趙六);
insert into teacher  values(null,蒼老師);
insert into teacher  values(null,文老師);
insert into teacher  values(null,陳老師);

select  *  from student;
select * from teacher;


--  維護關系   蒼老師有兩個學員 
insert into student_teacher values(1,1);
insert into student_teacher values(2,1);
insert into student_teacher values(3,1);

--  題目 顯示蒼老師的所有學員信息 
select s.*
from student s,teacher t,student_teacher st
where st.sid=s.id and st.tid=t.id and t.name=蒼老師;

一對多關系

案例說明:員工和部門

技術分享圖片

--  emp  設計 
drop table if exists emp;
create table if not exists emp(
empno int primary key auto_increment,
ename varchar(10) not null,
job varchar(20),
salary double(8,2),
mgr int(10),
bonus double(6,2),
hiredate date,
deptno int,
--  添加外鍵約束    constraint  約束   pk  primary key   fk foreigin key    references  參照
constraint  emp_dept_fk foreign key(deptno)  references dept(deptno)
);
--  新建dept表
drop table if exists dept;
create table if not exists dept(
deptno int primary key,
dname varchar(30),
dlocation varchar(255)
);

select * from emp;
select * from dept;
desc  emp;
show  tables;
--  外鍵約束  兩張表產生關聯   2種方式   1:  建表語句條件外鍵約束(常用)

-- 2: 表已經建好 添加外鍵約束  刪除外鍵約束
alter table emp drop foreign key emp_dept_fk;
alter  table  emp add constraint emp_dept_fk foreign key (deptno) references dept(deptno);
--
delete from emp;
delete from dept where deptno=10;

--  一對多的刪除  問題  
--   1:  部門刪除  員工全部幹掉     cascade  級聯  刪除 部門刪除  該部門所有的員工全部自動刪除
alter table emp drop foreign key emp_dept_fk;
alter  table  emp add constraint emp_dept_fk foreign key (deptno) references dept(deptno) on delete  cascade;
                
--  2: 部門刪除 員工留  更換部門號   部門刪除  員工保留 但是員工deptno --->null
   alter table emp drop foreign key emp_dept_fk;
alter  table  emp add constraint emp_dept_fk foreign key (deptno) references dept(deptno) on delete set null;
delete from dept where deptno=20;

建表原則:不需要創建第三方關系表,只需要在多方添加 一方主鍵作為 外鍵;

一對一關系

這種關系很少見到 負責人和工作室 夫妻關系

一個負責人 管理一個工作室

一個工作室 只有一個負責人

建表規則:在任一方添加對方主鍵 作為外鍵

--  1:1     夫妻  一夫一妻 
create  table husband(
id int primary key auto_increment,
name varchar(20)
);
create  table wife(
id int primary key auto_increment,
name varchar(20),
h_id int,
constraint husband_wife_fk foreign key(h_id) references husband(id)
);

insert into husband values(null,a);
insert into husband values(null,b);
insert into wife values(null,A,1);


--  查找出A的老公是誰?
select h.*
from husband h , wife w
where h.id=w.h_id and w.name=A;

用戶管理

創建用戶

-- 語法:CREATE USER 用戶名[@地址] IDENTIFIED BY ‘密碼‘;

-- 示例:創建一個名叫user1,密碼是123的用戶
-- 創建本地用戶:
CREATE USER user1@localhost IDENTIFIED BY 123;

-- 創建本地和遠程用戶
CREATE USER user1@% IDENTIFIED BY 123;

刪除用戶

-- 語法:drop USER 用戶名;

-- 示例:刪除用戶user1
drop USER user1;

修改用戶密碼

-- 語法:UPDATE USER SET PASSWORD=PASSWORD(‘密碼‘) WHERE USER=‘用戶名‘;
-- FLUSH PRIVILEGES;

-- 示例:
UPDATE USER SET PASSWORD=PASSWORD(1234) WHERE USER=user1;
FLUSH PRIVILEGES;

用戶授權

  • 授權
    -- 語法:Grant 權限1,權限2…… on 數據庫名.表名 to 用戶名@IP;
    
    -- 示例:
    GRANT SELECT,INSERT,UPDATE ON mydb1.* TO user1@localhost;
    GRANT ALL ON mydb1.* TO user1@localhost;
  • 取消授權
    -- 語法:REVOKE 權限1,權限2…… on 數據庫名.表名 from 用戶名@IP;
    
    -- 示例:
    REVOKE SELECT,INSERT,UPDATE ON mydb1.* FROM user1@localhost;

案例練習

  鏈接: https://pan.baidu.com/s/1miaJuQ0 密碼: xeb4

MySQL:(二)