Oracle SQL語句總結備查

0. 前言

本文以自己在學習、練習和工作中遇到的與Oracle相關的sql語句,現以筆記的形式在博文中給出,主要是爲自己以後備忘查詢,如有錯誤希望各位仁心發現後幫忙指出,本人將非常感謝。


1. 數據庫基本操作

1.1 常用語句

--查看oracle版本
select * from v$version;       
select * from product_component_version;    
--查看Oracle數據庫中所有表空間的保存路徑
select file_name,tablespace_name from dba_data_files --第一種方式
select name from v$datafile; --第二種方式
--查看到控制文件存放位置。
select name from v$controlfile;
--顯示oracle數據庫的各種參數信息
show parameter;
--更改ORACLE 用戶:OPEN表示賬戶爲解鎖狀態;EXPIRED表示賬戶爲過期狀態(需要設置口令才能解除此狀態);LOCKED表示賬戶爲鎖定狀態。)
select username,account_status from dba_users; --查看所有的賬戶狀態
alter user hr account unlock;   --用ALTER USER語句爲hr賬戶解鎖
alter user hr identified by hr; --用ALTER USER語句爲hr賬戶設置口令

1.2 Dos相關

ed --修改上一次出現錯誤的sql語句,將在默認的編輯器中打開
host cls        --windows清屏
host clear      --linux清屏
show user;      --顯示當前用戶
save c:\sql;    --保存腳本
@c:\a.sql;      --加載並執行腳本
spool c:\聽課筆記.txt;  --錄屏命令開始,保存到特定文件
spool off;              -- 錄屏結束命令
set pagesize 20;        --設置每頁顯示的數據行數(表頭、空行都算)
desc emp;               --查看某張表

2. 表操作

2.1 增刪改(CDU)

--指定數據表中某列爲主鍵(指定tuser表中user_id列爲主鍵,主鍵約束名爲tuser_PK)
alter table tuser add constraint tuser_PK  primary key(user_id)
--刪除主鍵名(無主鍵約束名的情況)(刪除tuser表的主鍵)
select * from user_cons_columns; --先查詢出表的主鍵約束名
alter table tuser drop constraint SYS_C0010342;
--清除表中的數據
delete from tablename where 1=1
truncate Table tablename

2.2 查詢(R)

2.2.1 普通查詢語句

--查詢當前用戶所有的表
select * from tab;  --tab:數據字典,可以查看當前用戶下的所有表
--查詢員工的所有信息
select * from  emp; 
select linesize 120;  --設置行寬(設置每行120個字符)
col ename for a8 
col sal for 9999  --9代表數字,表示sal最多顯示4位
/ --執行上述所有sql語句
--查詢員工信息:員工號  姓名 月薪
select empno,ename,sal;
--查詢員工信息:員工號  姓名 月薪 年薪
select empno,ename,sal,sal*12;
--錯誤語句示例
--★知識點:員工號,姓名是沒有區別的,但是員工號和職位是有區別的
select empno as "員工號", ename as "姓名",sal 月      薪,job 職位;--錯誤原因,別名中間不能有空格  
select empno as "員工號", ename as "姓名",sal "月      薪",job 職位;--修改後
--★distinct去掉重複的(作用於後面所有的列,只有當後面的所有列值都相同對distinct才起作用)
select distinct deptno from emp;

2.2.2 條件查詢語句

--查詢10號部門的員工信息
select * from emp  where deptno=10;
--查詢入職日期爲17-11月-81的員工
select *  from emp  where hiredate='17-11月-81';
select *   from emp where hiredate='1981-11-17';  --錯誤格式
select sysdate from dual; --可以通過打印系統時間來查看系統時間格式
col parameter for a30 --確定顯示格式
select *  from v$nls_parameters; --查詢表中數據字典的參數
alter session set nls_date_format='yyyy-mm-dd';--修改日期格式
--查詢薪水1000~2000之間的員工
select   from emp where sal between 1000 and 2000; --第一個參數必須比第二個小
--查詢部門號是10和20的員工
select * from emp  where deptno in (10,20);
--查詢名字以S打頭的員工
select *  from emp where ename like 'S%';
--查詢名字是4個字的員工
select *  from emp where ename like '____';
--查詢名字中含有下劃線的員工
select *  from emp where ename like '%\_%' escape '\\';
--★order by後面+列名  表達式  別名 序號
--查詢員工信息 按照年薪排序
select ename,sal,sal*12  from emp order by sal*12;
--order by 後面加別名和序號
select ename,sal,sal*12 年薪 from emp * order by 4;
--order by 後面+多列(order by作用於後面所有的列,先按照第一列排序)
select *  from emp  order by deptno,sal;
--desc只作用於離他最近的一列
select * rom emp order by deptno desc,sal desc;
--查詢員工信息,按照獎金排序(獎金還有空值)
select * from emp order by comm;
select * from emp  order by comm desc nulls last; --表示沒有數據的(null值的)排在後面

2.2.3 多表查詢

--理解笛卡爾集
--等值連接-->查詢員工信息: 員工號 姓名 月薪 部門名稱
select e.empno,e.ename,e.sal,d.dname from emp e,dept d where e.deptno=d.deptno;--如果不給任何的條件,則出現的是笛卡爾集
--不等值連接-->查詢員工信息: 員工號 姓名 月薪 工資級別
select e.empno,e.ename,e.sal,s.grade from emp e,salgrade s where e.sal between s.losal and s.hisal;
--★★外連接
--按部門統計員工人數: 部門號 部門名稱 人數
select d.deptno 部門號,d.dname 部門名稱,count(e.empno) 人數 from emp e,dept d where e.deptno=d.deptno group by d.deptno,d.dname;--★等值連接形式出錯,有一個部門沒有員工,統計不到
--希望在最後的結果中,包含某些不成立的記錄
select d.deptno 部門號,d.dname 部門名稱,count(e.empno) 人數 from emp e,dept d where e.deptno(+)=d.deptno group by d.deptno,d.dname;
--★★自連接
--查詢員工信息:***的老闆是***(自連接:通過表的別名,將同一張表視爲多張表)
select e.ename||'的老闆是'||b.ename from emp e,emp b where e.mgr=b.empno;
--【注意:自連接操作不太適合操作數據量太大的表,因爲存在笛卡爾集,數據的條數是平方的關係】
--★★層次查詢(解決上面問題)
select level,empno,ename,sal,mg  from emp  connect by prior empno=mgr start with mgr is null order by 1; --前面操作的員工號等於後面操作的老闆號
/*執行過程: 1. KING: start with mgr is null ---> empno=7839
                        2. where mgr = 7839; ---> 7566 7698 7782
                        3. where mgr in (7566 7698 7782) */

2.2.4 子查詢

/*
1. 括號
2. 合理的書寫風格
3. 可以主查詢的where select from having後面放置子查詢
4. 【不可以在主查詢的group by後面放置子查詢】
5. ★強調from後面的子查詢
6. 主查詢和子查詢可以不是同一張表,只要子查詢返回的結果 主查詢可以使用即可
7. 一般不在子查詢使用order by,但在Top-N分析問題中 必須使用order by
8. 一般先執行子查詢,再執行主查詢;但相關子查詢除外
9. 單行子查詢只能使用單行操作符 多行子查詢只能使用多行操作符
10. 子查詢中null
*/
--查詢工資比SCOTT高員工
select * from emp where sal > (select sal  from emp where ename='SCOTT');
--【可以主查詢的where select from having後面放置子查詢】
select ename,sal,(select job from emp where empno=7839) 一列 from emp;
--查詢員工的姓名和薪水【強調from後面的子查詢】
select * from (select ename,sal from emp);--將from後面的這個集合看成一個表
--查詢部門名稱爲SALES的員工信息【主查詢和子查詢可以不是同一張表,只要子查詢返回的結果 主查詢可以使用即可】
select * from emp where deptno=(select deptno from dept where dname='SALES');
select e.* from emp e,dept d  where e.deptno=d.deptno and d.dname='SALES'; --也可以用多表查詢
 --查詢部門名稱是SALES和ACCOUNTING的員工
select * from emp where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');
--查詢部門名稱是SALES和ACCOUNTING的員工【in 在集合中】
select * from emp where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');
--查詢工資比30號部門任意一個員工高的員工信息【 any: 和集合中、任意一個值比較,將多行集合變成單行數據】
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);  --也可使用min函數
--查詢工資比30號部門所有員工高的員工信息【 all:和集合的所有值比較】
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); --也可使用max函數
--是老闆的員工(是老闆的員工的員工號在mgr集合當中)
select *  from emp  where empno in (select mgr from emp); 
--★查詢不是老闆的員工(emp表中的mgr含有null值,不能使用not in)
select *  from emp  where empno  not in (select mgr from emp);  --是錯誤的
select * from emp  where empno not in (select mgr from emp where mgr is not null); --正確的
)

2.2.5 集合運算

--查詢部門號是10和20的員工信息
select * from emp where deptno in (10,20);
select * from emp where deptno=10 or deptno=20;
--按照部門統計各部門不同工種的工資情況
select deptno,job,sum(sal) from emp group by rollup(deptno,job);
select deptno,job,sum(sal) from emp group by deptno,job union  
        select deptno,sum(sal) from emp group by deptno union 
        select sum(sal) from emp; --錯誤:ORA-01789: 查詢塊具有不正確的結果列數 
/*【 注意的問題】錯誤原因分析:
 1. 參與運算的各個集合必須列數相同 且類型一致
 2. 採用第一個集合的表頭作爲最後的表頭
 3. 如果排序,必須 在每個集合後使用相同order by
 4. 括號
 */
select deptno,job,sum(sal) from emp group by deptno,job union
        select deptno,to_char(null),sum(sal) from emp group by deptno union
        select to_number(null),to_char(null),sum(sal) from emp;
)

3. 函數

3.1 通用函數

--nvl2(a,b,c) 當a=null時,返回c,否則返回b
select sal*12+nvl2(comm,comm,0) from emp;
--COALESCE :從左往右找到第一個不爲null的值
select comm,sal,COALESCE(comm,sal) from emp;

3.2 單行函數

--★單行函數中的字符函數====================================================
--大小寫轉換
select lower('Hello WORLd') 轉小寫,upper('Hello WORLd') 轉大寫, initcap('hello world') 首字母大寫 from dual;
--substr(a,b) 從a中,第b位開始取,取右邊所有的字符
select substr('hello world',3) from dual;
--substr(a,b,c) 從a中,第b位開始取,取c位
select substr('hello world',3,4) from dual;
--length 字符數  lengthb 字節數
select length('hello world')  字符數,lengthb('hello world')  字節數  from dual;
--instr(a,b) 從a中查找b,找到返回下標,否則返回0
select instr('hello world','ll') from dual;
--lpad 左填充 rpad右填充
select lpad('abcd',10,'*') 左,rpad('abcd',10,'*') 右  from dual;
--trim: 去掉前後指定的字符
select trim('H' from  'Hello WorldH') from dual;
 --replace 替換
 select replace('hello world',  'l','*') from dual;

-- ★單行函數中的數值函數====================================================
 --四捨五入,也可以操作日期
select ROUND(45.926, 2) 一,ROUND(45.926, 1) 二,ROUND(45.926, 0) 三, ROUND(45.926, -1) 四, ROUND(45.926, -2) 五 from dual;
--截斷,也可以操作日期
select TRUNC(45.926, 2) 一,TRUNC(45.926, 1) 二,TRUNC(45.926, 0) 三, TRUNC (45.926, -1) 四, TRUNC(45.926, -2) 五 * from dual;

--★單行函數中的日期函數====================================================
--Oracle中的日期型數據含有兩個值,日期和時間。默認日期格式:DD-MON-RR
select sysdate from dual;   --當前日期
--昨天 今天 明天(不允許日期 + 日期 )
select (sysdate-1) 昨天, sysdate 今天,(sysdate+1) 明天  from dual; --+1單位爲天
--計算員工的工齡
select ename,hiredate,(sysdate-hiredate) 天, (sysdate-hiredate)/7 星期,(sysdate-hiredate)/30 月,(sysdate-hiredate)/365from emp;
--MONTHS_BETWEEN 返回兩個日期相差的月數
select ename,hiredate,(sysdate-hiredate)/30 一,MONTHS_BETWEEN(sysdate,hiredate) 二 from emp;
--ADD_MONTHS: 加上若干個月
select ADD_MONTHS(sysdate,100) from dual;
--next_day:下一個星期三
select next_day(sysdate,'星期三') from dual;
--提示:next_day應用: 每個星期一做數據備份(涉及分佈式數據庫)
--顯示當前時間: 2013-06-19 14:45:23今天是星期三
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss"今天是" day') from dual;
--制定格式輸出:查詢員工薪水:(格式) 兩位小數 貨幣代碼  千位符
select to_char(sal,'L9,999.99') from emp;

3.3 多行函數

--工資總額
select sum(sal) from emp;
--平均工資
select sum(sal)/count(*) 一,avg(sal) 二 from emp;
--平均獎金: 空值 5(組函數自動濾空)
select sum(comm)/count(*) 一, sum(comm)/count(comm) 二, avg(comm) 三 from emp; --三個平均值,二三是相同的,一是不同的
--理解:空值 5: 組函數自動濾空
select count(*), count(comm)  from emp; --第一個是14第二個是4(只統計非null的情況),用哪種情況要區分業務要求
--屏蔽組函數的自動濾空(爲空時用0代替),
select count(*), count(nvl(comm,0))  from emp;
--求每個部門的平均工資
select deptno,avg(sal)  from emp group by deptno; ---寫語句時注意邏輯順序(格式:select a,組函數(x) from ** group by a;)
--分組數據--求每個部門的平均工資
select deptno,avg(sal) from emp group by deptno;
--按照部門統計各部門不同工種的工資情況
select deptno,job,sum(sal) from emp group by rollup(deptno,job);
--指定顯示格式,按照部門統計各部門不同工種的工資情況
break on deptno skip 2 --指定顯示格式相同deptno只顯示一次;不同deptno之間空格兩行
select deptno,job,sum(sal) from emp group by rollup(deptno,job);
--取消上面指定的顯示格式
break on null

附錄

附錄1:創建表空間代碼模板

-- 創建數據表空間
create tablespace 表空間名_dat
datafile 'd:\\oracle\\oradata\\表空間名_dat.dbf' 
size 64m autoextend on next 100m
default storage (
    initial 128K 
    next 128K 
    minextents 1 
    maxextents 505 
    pctincrease 50
);

-- 創建臨時表空間
create temporary tablespace 表空間名_tmp
tempfile  'd:\\oracle\\oradata\\表空間名_tmp.dbf' 
size 20m autoextend on next 10m extent management local uniform size 10m;

-- 創建索引表空間
create tablespace 表空間名_tmp_idx
datafile 'd:\\oracle\\oradata\\表空間名_tmp_idx.dbf' 
size 128m autoextend on next 100m 
default storage (
    initial 64K 
    next 64K 
    minextents 1 
    maxextents 505 
    pctincrease 50
);

-- 創建表用戶
create user identified by 用戶名 default tablespace 表空間名_dat temporary tablespace 表空間名_tmp;

-- 爲用戶授權
grant connect, resource ,dba to 用戶名;
發佈了56 篇原創文章 · 獲贊 15 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章