ORACLE筆記

SQL的類型

  1. DML(Data Manipulation Language 數據操作語言): insert update delete select
  2. DDL(Data Definition Language 數據定義語言): create/alter/drop/truncate table
    ? create/drop view,sequence,index,synonym(同義詞)
  3. DCL(Data Control Language 數據控制語言): grant(授權) revoke(撤銷權限)

DDL

  • 創建表:

create table tname(c1 t1 default v,c2 t2,,);

  • 子查詢:

create table ttemp as select * from emp where 1=2;(不要數據)

create table ttemp as select * from emp;(要數據)

  • 修改表:

alter table tname add col type;--追加列

alter table tname modify col newtype;--修改類的類型

alter table tname drop column col; --刪除列

alter table tname rename column cname to cnewname;--修改列名

rename tname to tnewname--修改表名

  • 刪除表:

drop table tname; 把表放入回收站

truncate table tname;把表刪除重建

  • 表的重構(去掉因刪除造成的碎片):

alter table emp move

  • 回收站:

select * from user_recyclebin; 查看回收站

purge recyclebin; 清空回收站

select * from "回收站的表名";可以看到數據

flashback table tname to before drop;--恢復表(閃回)

DML

  • insert語句

insert into dept(deptno,dname) values(70,'oracle');

  • 通過子查詢插入數據

insert into tname select .. from tname2;

  • update語句

update dept set dname='c++' where deptno=80;

  • delete語句

delete from dept where deptno=80;

delete 和truncate區別

  1. delete 逐條刪除,truncate先刪除表,再重建
  2. delete是DML(可以回滾) truncate是DDL(不可以回滾)
  3. delete 不會釋放空間;truncate會
  4. delete會產生碎片 truncate不會
  5. delete可以閃回(flashback) truncate不可以

基本查詢

  • 當前用戶
    • show user;
  • 用戶下所有的表
    • select * from tab;
  • 列的別名
    • col as "別名" (col as 別名)
    • col "別名" (原名顯示)
    • cal 別名 (自動轉大寫,不能和oracle關鍵字沖突)
    • 列的別名最好用雙引號括起來
  • 數據字典
    • select * from v$nls_parameters;
  • 修改日期格式
    • alter session set NLS_DATE_FORMAT='yyyy-mm-dd';
  • between and
    • 1.含邊界 2. 小值在前 大值在后
    • 查詢薪資大于等于1000并且小于等于2000的員工信息
    • select * from emp where sal between 1000 and 2000;
  • 去掉重復行
    • select distinct deptno from emp;
  • 連接字符串 concat() or ||
    • select concat('your name:',ename) from emp;
    • select 'your name:'||ename from emp;
  • 模糊查詢like 和轉義字符 escape (%零或多個,_一個)
    • 查詢名字A打頭的員工信息
    • select * from emp where ename like 'A%';
    • 查詢名字第二個字母是L的員工信息
    • select * from emp where ename like '_L%';
    • 查詢出名字中帶_字符的信息
    • select * from emp where name like '%{_%' ESCAPE '{'
  • null條件查詢 is null 或 is not null
    • select * from emp where COMM is null; 沒有獎金的員工
    • null值最大,所以desc的時候,null排在最前面
    • select * from emp order by comm desc nulls last
  • desc 查看對象的定義信息
    • desc dept; 查看表

Oracle中的函數查詢

基本格式:

  • select 函數名 from dual;

數字函數

round(number,小數位數正負都行) 四舍五入

  • round(125.315) would return 125

trunc(number,小數位數) 截斷

  • trunc(-125.815, 2) would return -125.81

字符函數

  • substr(a,b) 從a中,第b為開始
  • substr(a,b,c) 從a中,第b開始,取c個
  • length(a) 字符長度
  • lengthb(a) 字節長度
  • instr(a,b) 在a中查詢b的位置
  • lpad(a,n,c) 左填充
  • rpad(a,n,c) 右填充
  • trim('H' from 'HsssH') 去掉前后指定的字符
  • replace('hello','l','*') 替換

日期函數

  • sysdate:系統時間(格式),格式化顯示時間
    • select to_char(sysdate,'yyyy-mm-dd') from dual;
  • systimestamp:系統時間戳 :精度更高,格式化顯示時間
    • select to_char(systimestamp,'yyyy-mm-dd hh24:mi:ss:ff') from dual;

日期的運算:計算員工工齡

  • months_between (sysdate,hiredate)月
  • sysdate-hiredate 天
  • 加月 add_months(sysdate,n) n可正負
  • 月最后一天 last_day(sysdate)
  • 下一個星期: next_day(sysdate,'星期一')下個星期一的日期
  • 四舍五入 針對日期函數:round(to_date ('22-AUG-03'),'YEAR') would return '01-JAN-04'
  • 截斷 針對日期函數:trunc(to_date('22-AUG-03'), 'YEAR') would return '01-JAN-03'

轉換函數

  • number--> character to_char(sal,'L9,999.99') 人民幣格式字符串
  • select to_char(sal,'L9,999.99') from emp;
  • character--->number to_number('99.99')
  • select to_number('99.99') from dual;
  • date---->character to_char(sysdate,'yyyy-mm-dd hh24:mi:ss "今天"day')
  • select to_char(sysdate,'yyyy-mm-dd') from dual;
  • character-->dateto_date('2016-11-23','yyyy-mm-dd')
  • select to_date('2016-11-13','yyyy-mm-dd') from dual;

其他函數

  • nvl(e1,e2) e1為null時返回e2

  • nvl2(e1,e2,e3) e1為null 返回e3 否則返回e2

  • nullif(a,b) 當a=b的時候 返回null 否則返回a

  • coalesce(e1,e2,e3,,,) 從左到右 找第一個不為null的值

  • decode函數

    • 語法:decode(exp,ser1,res1,ser2,res2,,,,defualt);

    • 案例:decode(job,'manager',sal+1000,,,,,sal+100);

    • decode函數的原理是case語句:

    • 語法:
      case  exp
        when  com_epr then return_exp
        when  com_epr then return_exp
        when  com_epr then return_exp
        else  return_exp
      end;
      
      案例:
      select  sal 漲前,
          case job 
              when 'manager' then sal + 100
              when ....
              else sal+300
          end  漲后
      
  • 行轉列wm_concat()

    • select deptno,wm_concat(ename) from emp group by deptno;
  • exists函數,是否有記錄的函數

    • select * from dept where exists(select 1 from emp where emp.deptno=dept.deptno)

分組查詢

按列或者函數分組,分組后select后面只能跟分組之后的列,或聚合函數,或子查詢

--統計每年入職的員工人數
select to_char(hiredate,'yyyy') y, count(1) from emp group by to_char(hiredate,'yyyy'); 
--每個部門的平均工資
select avg(sal),deptno from emp group by deptno;

多表查詢

--等值連接
select * from emp,dept where emp.deptno = dept.deptno;
--不等值連接
select * from emp,dept where emp.deptno <> dept.deptno;
--內連接
select * from emp e inner join dept d on e.deptno = d.deptno; 
--外連接
--左外連接
select  * from emp e left join dept d on e.deptno = d.deptno; 
--左外連接
select  * from emp e ,  dept d where  e.deptno = d.deptno(+); 
--右外連接
select  * from emp e right join dept d on e.deptno = d.deptno; 
--右外連接
select  * from emp e ,  dept d where  e.deptno(+) = d.deptno; 
--全外連接
select  * from emp e full join dept d on e.deptno = d.deptno;  

自連接不適合操作大表

Oracle中的事務

  1. 起始標志:事務中第一題DML語句
  2. 結束標志: 提交: 顯式 commit
    ? 隱式 正常退出exit,DDL,DCL
    ? 回滾 顯式 rollback
    ? 隱式 非正常退出,掉電,宕機

--定義保存點

savepoint a;

—回滾到a;

rollback to savepoint a;

oracle分頁

 select *
 from   (select rownum r,e1.*
     from (select * from emp order by sal) e1
     where rownum <=8
    )
 where r >=5;

子查詢

注意的問題

  1. 括號
  2. 合理的書寫風格
  3. 可以在主查詢的where select having from后面放置子查詢
  4. 不可以在group by后面放置子查詢
  5. 強調from后面的子查詢
  6. 主查詢和子查詢可以不是同一張表;只要子查詢返回的結果主查詢可以使用即可
  7. 一般不在子查詢中排序;但在Top-N分析問題中,必須對子查詢排序
  8. 一般先執行子查詢,再執行主查詢;但相關子查詢例外
  9. 單行子查詢只能使用單行操作符;多行子查詢只能使用多行操作符
  10. 子查詢中的null

可以在主查詢的where select having from后面放置子查詢

select empno,ename,sal,(select job from emp where empno=7839) 第四列

2 from emp;


     EMPNO ENAME             SAL 第四列                                                                                                                                                                 
---------- ---------- ---------- ---------                                                                                                                                                              
      7369 SMITH             800 PRESIDENT                                                                                                                                                              
      7499 ALLEN            1600 PRESIDENT                                                                                                                                                              
      7521 WARD             1250 PRESIDENT                                                                                                                                                              
      7566 JONES            2975 PRESIDENT                                                                                                                                                              
      7654 MARTIN           1250 PRESIDENT                                                                                                                                                              
      7698 BLAKE            2850 PRESIDENT                                                                                                                                                              
      7782 CLARK            2450 PRESIDENT                                                                                                                                                              
      7788 SCOTT            3000 PRESIDENT                                                                                                                                                              
      7839 KING             5000 PRESIDENT                                                                                                                                                              
      7844 TURNER           1500 PRESIDENT                                                                                                                                                              
      7876 ADAMS            1100 PRESIDENT                                                 

強調from后面的子查詢

查詢員工信息:員工號 姓名 月薪
select * 2 from (select empno,ename,sal from emp);


       EMPNO ENAME             SAL                                                                                                                                                                        
---------- ---------- ----------                                                                                                                                                                        
      7369 SMITH             800                                                                                                                                                                        
      7499 ALLEN            1600                                                                                                                                                                        
      7521 WARD             1250                                                                                                                                                                        
      7566 JONES            2975                                                                                                                                                                        
      7654 MARTIN           1250                                                                                                                                                                        
      7698 BLAKE            2850                                                                                                                                                                        
      7782 CLARK            2450                                                                                                                                                                        
      7788 SCOTT            3000                                                                                                                                                                        
      7839 KING             5000                                                                                                                                                                        
      7844 TURNER           1500                                                                                                                                                                        
      7876 ADAMS            1100                                                                                                                                                                        

     EMPNO ENAME             SAL                                                                                                                                                                        
---------- ---------- ----------                                                                                                                                                                        
      7900 JAMES             950                                                                                                                                                                        
      7902 FORD             3000                                                                                                                                                                        
      7934 MILLER           1300                                                                                                                                                 

in 在集合中

查詢部門名稱是SALES和ACCOUNTING的員工
select *
  from emp
  where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');

any 和集合中任意一個值比較

查詢工資比30號部門任意一個員工高的員工信息

select *
from emp
* where sal > any (select sal from emp where deptno=30)

===

select *
from emp
* where sal > (select min(sal) from emp where deptno=30)

all: 和集合中的所有值比較

查詢工資比30號部門所有員工高的員工信息

select *
 from emp
 where sal > all (select sal from emp where deptno=30);
 
 ===
 
select *
from emp
* where sal > (select max(sal) from emp where deptno=30)

集合運算

union 并集:兩個集合取并集,自動排序,去掉重復行

select ename,sal,deptno from emp where sal > 1000
union
select ename,sal,deptno from emp where deptno = 30;

union all 并集:兩個結合取并集,不排序,不去掉重復行

select ename,sal,deptno from emp where sal > 1000
union all
select ename,sal,deptno from emp where deptno = 30;

intersect 交集:第一個集合減第二個集合

select ename,sal,deptno from emp where sal > 1000
intersect
select ename,sal,deptno from emp where deptno = 30;

minus 差集:第一個集合減第二個集合

select ename,sal,deptno from emp where sal > 1000
minus
select ename,sal,deptno from emp where deptno = 30;

SQL> 注意的問題:
SQL> 1. 參與運算的各個集合必須列數相同 且類型一致
SQL> 2. 采用第一個集合表頭作為最后表頭
SQL> 3. order by 永遠在最后
SQL> 4. 括號

SQL>  select deptno,job,sum(sal) from emp group by deptno,job
  2   union
  3   select deptno,sum(sal) from emp group by deptno
  4   union
  5   select sum(sal) from emp;
 select deptno,sum(sal) from emp group by deptno
 *
第 3 行出現錯誤: 
ORA-01789: 查詢塊具有不正確的結果列數 
SQL>  select deptno,job,sum(sal) from emp group by deptno,job
  2   union
  3   select deptno,to_char(null),sum(sal) from emp group by deptno
  4   union
  5   select to_number(null),to_char(null),sum(sal) from emp;

order by 后面 + 列,表達式,別名,序號

select empno,ename,sal,sal*12
 from emp
 order by sal*12 desc;
select empno,ename,sal,sal*12 年薪
from emp
* order by 年薪 desc
select empno,ename,sal,sal*12 年薪
from emp
* order by 4 desc
select empno,ename,sal,sal*12 年薪
from emp
* order by 5 desc
SQL> /
order by 5 desc
         *
第 3 行出現錯誤: 
ORA-01785: ORDER BY 項必須是 SELECT-list 表達式的數目 

多個列的排序

order by 作用于后面所有的列,先按照第一個列排序,如果相同,再按照第二列排序;以此類推

select *
from emp
order by deptno,sal;

desc 只作用于離他最近的一列

select *
from emp
* order by deptno desc,sal desc

用desc的時候

如果有null會被排在上面,因為null最大

select *
from emp
order by comm desc
* nulls last

表的高級管理

create table t_student(t_id integer,t_sex char(2),t_age integer);

create table t_teacher(tc_id integer primary key,tc_name varchar2(10));

--給學生表添加外鍵列
alter table t_student add  tc_id integer;
--主鍵約束
alter table t_student add constraint pk_t_student_t_id primary key(t_id);
--唯一性約束
alter table t_student add constraint unique_stu_name unique(t_name);
--非空約束
alter table t_student modify t_name not null;
--外鍵約束
alter table t_student add constraint fk_stu_tc_id_tea foreign key(tc_id) references t_teacher(tc_id);
--檢查約束
alter table t_student add constraint ck_age check(t_age between 1 and 200);
alter table t_student add constraint ck_sex check(t_sex in ('男','女'));

SQL優化原則

  • 理論上,盡量使用多表查詢
  • 盡量不要使用集合運算
  • 盡量使用列名代替*
  • where順序: 右--》 左

SQL中的null

  • 包含null的表達式都為null
  • SQL> 2. null永遠!=null
  • 如果集合中,含有null,不能使用not in;但是可以使用in
    • 如果要查詢的話用exists函數代替in
    • select * from dept where exists(select 1 from emp where emp.deptno=dept.deptno)

表的三大范式

  • 所有的列都是不可分割的最小單元
  • 所有的非主鍵列都完全依賴主鍵列
  • 非主鍵列之間不存在傳遞依賴

數據庫設計原則

  • 分析系統中所有的數據(對象,表)
  • 確定數據與數據之間的關系(一對一,一對多,多對多)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容