文章目錄
學習目標
1、92語法
當我們想要的數據來自於多張表時就需要使用表連接。
- 在表連接過程中,如果想某一張表中的所有數據無論是否滿足連接條件都顯示,可以把這張表設置爲主表;
- 主表:在連接位置,主表對面的連接條件有“(+)”,在外連接中主表的數據可以全部展示。
- 外鏈接
- 左外連接 : 主表在逗號左邊就是左連接
- 右外連接 : 主表在逗號右邊就是右連接
- 等值連接和非等值連接
注意:
- 表連接後,當使用的字段是多個表共同的字段時需要指明字段的出處
1.1、等值連接(在笛卡爾積的基礎上取條件列相同的值)
--查詢所有員工的員工信息和所在的部門信息
select * from emp e,dept d where e.deptno = d.deptno;
--30部門和20部門的員工信息與所在部門信息
select * from emp e,dept d where e.deptno = d.deptno and e.deptno in(20,30);
--查詢員工信息與員工薪資等級信息,所在部門信息
select *
from emp e, dept d, salgrade s
where sal between s.losal and s.hisal
and e.deptno = d.deptno;
1.2、非等值連接(>、<、!=、<>、between and):
--查詢員工信息與員工的薪資等級信息
select * from emp e,salgrade s where e.sal between s.losal and s.hisal;
--查詢員工信息與員工薪資等級信息,所在部門信息
select *
from emp e, dept d, salgrade s
where sal between s.losal and s.hisal
and e.deptno = d.deptno;
1.3、自連接:
--查詢經理人的編號、姓名、工資、部門編號
select e1.eno,e1.ename,e1.sal,e1.deptno from emp e1,emp e2 where e1.mgr=e2.empno;
1.4、外連接實例:
--查詢有上級的員工的信息以及上級經理人信息
select * from emp e1,emp e2 where e1.empno = e2.mgr;--沒有上級的King被自動過濾掉了
--查所有員工的信息以及上級經理人信息
--員工表爲主表
select * from emp e1,emp e2 where e1.mgr = e2.empno(+);--左外連接
select * from emp e1,emp e2 where e1.mgr(+) = e2.empno;--右外連接
2、99語法
表連接方式:
-
交叉連接 cross join —>笛卡爾積
-
自然連接(主外鍵、同名列) natural join -->等值連接
-
join using連接(同名列) -->等值連接(在要連接的表之間存在多個字段相同時使用)
-
[inner] join on 連接 -->等值連接、非等值、自連接 (可以實現一切連接方式,但關係列必須區分)
-
left|right [outer] join on|using(同名列) -->左(右)外連接
-
full join on|using(字段名) -->全連接,滿足直接匹配,不滿足 相互補充null ,確保 所有表的記錄 都至少出現一次
注意:
- 使用on時可以是等值連接,也可以是非等值連接(關鍵看on後面的連接條件),使用using一定是等值連接
2.1、cross join 笛卡爾積(對乘)
select * from emp,dept;
select *
from (select * from emp where deptno in 30)
cross join (select * from dept where deptno in 20);
2.2、natural join自然連接
--自然連接 natural join 自動根據同名字段|主外鍵關係
select ename,sal,deptno from emp natural join dept; --同名字段不能指明出
2.3、using連接
當存儲在多個同名字段時,可以指明使用哪個字段進行連接,且只能做等值連接。
--join using(等值連接字段名) 當存在多個同名字段,可以指明使用哪一個做等值連接
select ename,sal,deptno from emp join dept using(deptno);
2.4、do連接
使用do可以做任意連接(等值或非等值)。
--使用on實現等值連接
select * from emp e join dept d on e.deptno = d.deptno;
----------------------使用on實現非等值連接--------------------
--查詢員工薪資等級
select * from emp e join salgrade s on e.sal between s.lowsal and hisal;
-- 查詢非20部門並且薪資>1500的員工信息以及薪資等級信息(使用99中的join on 連接),並且按薪水降序
select *
from emp e
join salgrade s
on e.sal between s.losal and s.hisal
where e.deptno != 20
and sal > 1500
order by sal desc;
--查詢30部門的員工信息,所在部門信息,薪資等級情況,以及上級經理人信息
select *
from emp e1
join dept d
on e1.deptno = d.deptno
join salgrade s
on sal between losal and hisal
join emp e2
on e1.mgr = e2.empno
where deptno = 30;
2.5、外連接
想要某張表中不滿足連接條件的數據都顯示,把這張表定義爲主表,不滿足的部分用null補齊。
- 左外連接,left join on|using
- 右外連接,right join on|using
select * from emp e1 left join emp e2 on e1.mgr=e2.empno;
select * from emp e1 right join emp e2 on e1.mgr=e2.empno;
2.6、全連接
連接的表都作爲主表。是左連接和右連接集合的並集。
select * from emp e1 full join emp e2 on e1.mgr=e2.empno;
3、視圖
- 當某個結果集被反覆使用時就可以考慮添加視圖;
- 介於表和結果集之間的就是試圖,其實也是結果集,但是這個結果集可以被存儲,以後可以查詢試圖中的數據;
- 最大的優點:就是封裝查詢到的結果集,簡化sql;
- 合理使用試圖,不要濫用
語法:create or replace view 試圖名字 as 結果集 with read only;
--創建視圖
create or replace view vw_emp as select empno,ename,sal,deptno from emp where deptno !=10 with read only;
--查詢視圖中的數據
select * from vw_emp;
--刪除試圖
drop view vw_emp;
--如果權限不夠
--切換管理員sys用戶
--授權: grant dba to scott;
--回收: revoke dba from scott;
習題:
--查詢每個部門中所有經理的人的平均薪資,以部門爲單位,求出最低平均薪資的那個部門的部門名稱
---------------------------- 不使用視圖 ----------------------------
--步驟1:計算各個部門經理的平均工資
select e2.deptno num, avg(e2.sal) avg_sal
from emp e1
join emp e2
on e1.mgr = e2.empno
group by e2.deptno;
--步驟2:最低平均工資
select min(avg(e2.sal))
from emp e1
join emp e2
on e1.mgr = e2.empno
group by e2.deptno;
--獲得部門名稱
select num,t2.dname
from (select e2.deptno num, avg(e2.sal) avg_sal
from emp e1
join emp e2
on e1.mgr = e2.empno
group by e2.deptno) t1 join dept t2 on t1.num = t2.deptno
where avg_sal = (select min(avg(e2.sal))
from emp e1
join emp e2
on e1.mgr = e2.empno
group by e2.deptno);
---------------------------- 使用視圖 ----------------------------
--創建視圖
create or replace view vw_avgsal as select e2.deptno num ,avg(e2.sal) avg_sal from emp e1 join emp e2 on e1.mgr=e2.empno group by e2.deptno;
--查找最小平均值
select min(avg_sal) from vw_avgsal;
--獲得部門名稱
select deptno, dname
from vw_avgsal v
join dept d
on v.num = d.deptno
where avg_sal = (select min(avg_sal) from vw_avgsal);
4、索引
索引是數據庫的對象之一,用於優化數據庫的查詢。
特點:
- 在對大量數據進行查詢的時候效率較高,數據量較少時反而效率低。
- 索引的創建與刪除完全不影響字段的使用。
- 在唯一字段或數據重複量不大的字段可以使用索引。
- Oracle中主動爲主鍵設置索引。
語法:
創建索引:create index 索引名 on表名 (字段列表…)
刪除索引:–drop index 索引名
--創建索引
create index index_sal on emp(sal);
--刪除
drop index index_sal;
5、設計表
- 設計表時要滿足三範式。
- 表之間的關係有:一對一、一對多、多對多
創建表的約束問題:
- 創建字段的時候給出字段約束;
- 在創建表的結構與結束之間給出約束;
- 創建表結束後追加約束。
約束的添加:
- 物理約束:在表上添加約束
- 邏輯約束:在java代碼層面添加檢查操作,符合條件的在存入數據庫,這樣靈活性更高。
約束分類:
-
主鍵約束:關鍵字primary key
-
外鍵約束:foreign key(字段名)
-
非空約束:not null
-
檢查約束:check(檢查條件)
-
唯一約束:unique(字段名)
-
默認值:default(默認值)
5.1、創建表的時候給出約束條件:
create table sxt_student(
sid number(5) constraints pk_sxt_student_sid primary key,--主鍵約束,給約束起名字
sname varchar2(15) not null,--非空約束
sage number(3) check(sage between 0 and 150),--檢查約束
ssex varchar2(3 char) check(ssex in('女','男')),--檢查約束
hiredate date default(sysdate),--默認值
cid number(5) constraints fk_sxt_student_cid references sxt_class(cid)--添加外鍵
)
5.2、創建字段後創建表結束前給出約束:
create table sxt_class(
cid number(5),
cname varchar2(15),
--添加約束(必須給出約束名)
constraints pk_sxt_class_cid primary key(cid)
)
5.3、創建表後添加約束:
--後續追加約束(必須給出約束名)
alter table sxt_student add constraints pk_sgender check(sgender in('男','女'));
5.4、刪除約束:
--刪除約束
alter table sxt_student drop constraints sxt_student_sname_notnull;
5.5、添加數據:
語法:insert into 表名 [(字段列表)] values(值列表); 添加記錄
--逐個字段添加(也可以同時添加多個字段)
insert into sxt_class(cid) values(1002);
--一次性添加所有字段
insert into sxt_class values(1001,'java36');
insert into sxt_student values(01,'張三',18,'男',sysdate,1001);
--一次性添加部分字段
insert into sxt_class(id,name,pwd) values(123,'zwl','1232')
5.6、刪除數據
語法:delete [from] 表名 where 過濾行記錄
- delete 可以刪除指定部分記錄,刪除全部記錄
- 從表中的數據可以直接刪除;
- 刪除主表數據:
- 主鍵沒有被引用可以直接刪除
- 被引用了:
- 默認 先刪除從表引用的數據,再刪除被引用的主表數據
- 添加外鍵約束時,on delete set null 刪除主表數據的同時,從表引用字段設置爲null
- 添加外鍵約束時,on delete cascade 刪除主表數據的同時,級聯刪除從表中引用了該主鍵作爲外鍵的從表記錄。
-- 刪除表數據
delete from sxt_class where cid=1002;
5.7、更新數據
要求:
- 記錄存在
- 類型、長度兼容
- 個數相同
update 表名 set 字段=值 [,…] where 過濾行記錄;
update users set name='lisa' where id=123
5.7、刪除表
-
默認先刪除從表再刪除主表
-
刪除的主表中沒有字段作爲其他表的外鍵時可以直接刪除;
-
級聯:刪除主表的同時刪除從表中對應的外鍵約束
--簡單刪除刪除
drop table sxt_student;
--cascade constraints刪除表的同時級聯刪除約束
drop table sxt_class cascade constraints;
5.8、追加外鍵約束
- 級聯:刪除主表時,使用該主表中的主鍵作爲外鍵的從表數據一併刪除,使用關鍵字“on delete cascade”
- 刪除主表時,使用該主表中的主鍵作爲外鍵的從表數據將該外鍵置爲null,使用關鍵字“on delete set null”
--追加外鍵約束1
alter table sxt_student add constraints fk_sxt_student_cid_class foreign key(cid) references sxt_class(cid) on delete cascade;
--追加外鍵約束2
alter table sxt_student add constraints fk_sxt_student_cid_class foreign key(cid) references sxt_class(cid) on delete set null;
5.9、操作約束
查看某個用戶的約束:
select constraint_name, constraint_type
from user_constraints
where owner = upper('scott');
查看錶的約束:
select constraint_name,constraint_type
from user_constraints
where table_name=upper('tb_user');
查看字段名+約束:
select constraint_name, column_name
from user_cons_columns
where table_name = upper('tb_user');
約束的禁用和啓用:
ALTER TABLE tb_user disable constraint nn_user_name;
ALTER TABLE tb_user enable constraint nn_user_name;
刪除約束:
alter table tb_user drop constraint uq_user_email cascade;
修改約束:
--非空
alter table tb_user modify (username varchar2(20));
--默認
alter table tb_user modify (age default null);
5.10、爲表添加註釋
--加入註釋
comment on table sxt_student is '學生表';
comment on column sxt_student.sid is '學號,主鍵';
comment on column sxt_student.sname is '學生姓名';
comment on column sxt_student.hiredate is '入學日期';
comment on column sxt_student.sage is '年齡';
comment on column sxt_student.sgender is '性別';
comment on column sxt_student.cid is '班級編號';
6、表的其他操作
6.1、修改表結構
1、修改表名 :rename to
2、修改列名: alter table 表名 rename column to
3、修改類型: alter table 表名 modify(字段 類型)
4、修改約束: 先刪除 後添加
5、添加列: alter table 表名 add 字段 類型
6、刪除列:alter table 表名 drop column 字段
--修改表名
rename tb_txt to tb_txt_new;
--修改列名
alter table tb_txt_new rename column txtid to tid;
--修改類型
alter table tb_txt_new modify(tid varchar2(20));
--添加列
alter table tb_txt_new add col varchar2(30);
--刪除列
alter table tb_txt_new drop column col;
select * from tb_txt_new;
6.2、截斷數據(truncate)
截斷數據與刪除數據的區別:
- truncate的ddl中,不涉及事務就不能回滾;delete的dml ,涉及事務,可以回滾。
- truncate 截斷所有的數據 delete 可以刪除全部 或者部分記錄 。
- truncate從結構上檢查是否存在主外鍵,如果存在,不讓刪除;delete 從記錄上檢查是否存在主外鍵,如果存在,按參考外鍵約束進行刪除。
--拷貝表的結構的同時拷貝數據(where後是恆等式)
create table emp_his as select * from emp where 1=1;
--拷貝表的結構的同時不拷貝數據(where後不是恆等式)
create table emp_his as select * from emp where 1!=1;
select * from emp_his;
--截斷所有的數據
truncate table emp_his;
--不能截斷: truncate table dept;
6.3、序列sequence
使用工具|程序管理流水號(如主鍵),序列在創建時沒有與表關聯 ,在操作數據時纔會與表關聯。如果不使用序列工具,主鍵可能出現跳號的問題,或者每次增加一條新的記錄時還需要查看錶中當前主鍵編碼到什麼位置了,這樣比較麻煩,這時就可以使用序列(sequence)自動完成主鍵的編號。
- currval :當前值
- nextval:下個值
創建:
create sequence 序列名 start with 起始值 increment by 步進;
使用:
create sequence seq_tb_user start with 2 increment by 2;
drop sequence seq_tb_user;
select seq_tb_user.nextval from dual;
select seq_tb_user.currval from dual
刪除:
drop sequence 序列名