oracle常用語句和常用函數詳解
一、SQL分類
SQL語言共分爲四大類:數據查詢語言DQL,數據操縱語言DML,數據定義語言DDL,數據控制語言DCL。
(一) 數據查詢語言DQL
1、數據查詢語言DQL基本結構是由SELECT子句,FROM子句,WHERE子句組成;
2、select主要語法:
select * [distinct ] 列 as 列別名 from 表名
where 條件 //對每條數據進行過濾
group by 列 //對過濾後的數據進行分組
Having 分組條件 //對分組進行限制
order by 列 [asc(默認升序) | desc (降序)] ;
注意:給列或者表起別名也可以省略as
3、比較運算符:其中不等於有三種表示<> ,!=,^= 第一種用的多即<>.
[not] between and 介於二者之間 【not】 like 匹配字符串 %:表示0或多個字符 _:表示一個字符
is 【not】null 判斷是否爲null 【not】in 匹配其中的數值
4、字符和日期用單引號定界,日期格式比較敏感
(二)數據操縱語言DML
數據操縱語言DML主要有三種形式:
1、 插入:INSERT
(1)第一種形式無需指定要插入數據的列名,只需提供被插入的值即可:
INSERT INTO table_name VALUES (value1,value2,value3,...);
(2)第二種形式需要指定列名及被插入的值:
INSERT INTO table_name (column1,column2,column3,...) VALUES (value1,value2,value3,...);
2、更新:UPDATE
(1)語法:update 表名 set column1= value1, column2=Value2 where column=Value;
3、 刪除:DELETE
(1)語法:delete from 表名 where column=Value;
4、drop、delete和truncate的區別:
(1)當表被truncate 後,這個表和索引所佔用的空間會恢復到初始大小,Truncate是一個DDL操作,一旦執行會隱式提交,這就說明truncate無法rollback,所以執行之前需謹慎;如果要清空一個大表的所有數據行,truncate比delete高效;
(2)delete操作不會減少表或索引所佔用的空間。delete是一行一行操作,並且把記錄都存進日誌文件,可以恢復。(說明一下,無論任何恢復模式,都會記錄日誌)。
(3)drop語句將表所佔用的空間全釋放掉;drop語句刪除表結構及所有數據,並將表所佔用的空間全部釋放;drop是DDL,會隱式提交,所以,不能回滾,不會觸發觸發器。
總結:delete和truncate只刪除數據,不刪除表結構。drop刪除數據和表結構。
(三)數據定義語言DDL
1、數據定義語言DDL用來創建數據庫中的各種對象-----表(table)、視圖(view)、索引(index)、同義詞(syn)、聚簇(cluster)等
注意:DDL操作是隱性提交的!不能rollback
(四) 數據控制語言DCL
數據控制語言DCL用來授予或回收訪問數據庫的某種特權,並控制數據庫操縱事務發生的時間及效果,對數據庫實行監視等。如:
1、GRANT:授權。
(1)grant語法:grant 系統權限 to 角色名或者用戶名;grant 對象權限 on 表名 to 角色名或者用戶名;
注意:只有dba用戶可以給角色授予系統權限,只有表的擁有者纔可以將表的操作權授予其他用戶。原因:oralce對權限管理比較嚴謹,普通用戶之間也是默認不能互相訪問的,需要互相授權;
(2)grant命令可以給多個用戶批量授權:grant 系統權限 to 用戶名1 [,用戶名2]....。
(3)把角色授予用戶:grant 角色名 to 用戶名;
(4)撤銷權限命令語法:revoke 實體權限名|all on 表名 from 用戶名|角色名|public;或者 revoke 系統權限 from 用戶名;
注意:取消權限時,是級聯的。
2、ROLLBACK [WORK] TO [SAVEPOINT]:回退到某一點。
回滾---ROLLBACK
回滾命令使數據庫狀態回到上次最後提交的狀態。其格式爲:SQL>ROLLBACK;
3、COMMIT [WORK]:提交。
在數據庫的插入、刪除和修改操作時,只有當事務在提交到數據庫時纔算完成。在事務提交前,只有操作數據庫的這個人纔能有權看到所做的事情,別人只有在最後提交完成後纔可以看到。提交數據有三種類型:顯式提交、隱式提交及自動提交。下面分別說明這三種類型。
(1) 顯式提交
用COMMIT命令直接完成的提交爲顯式提交。其格式爲:SQL>COMMIT;
(2) 隱式提交
用SQL命令間接完成的提交爲隱式提交。這些命令是:ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。
(3) 自動提交
若把AUTOCOMMIT設置爲ON,則在插入、修改、刪除語句執行後,系統將自動進行提交,這就是自動提交。其格式爲:SET AUTOCOMMIT ON;
(五)表中字段的增加、修改、刪除和重命名
1、字段的增加語法:alter table tablename add (column datatype [default value][null/not null],….);說明:alter table 表名 add (字段名 字段類型 默認值 是否爲空);
2、字段的修改語法:alter table tablename modify (column datatype [default value][null/not null],….); 說明:alter table 表名 modify (字段名 字段類型 默認值 是否爲空);
3、字段的刪除語法:alter table tablename drop (column);說明:alter table 表名 drop column 字段名;
4、字段的重命名語法:alter table 表名 rename column 列名 to 新列名; (其中:column是關鍵字)
5、表的重命名語法:alter table 表名 rename to 新表名;
注意:Mysql對於有數據和沒數據的表字段類型都可以隨意修改,不過oracle就不一樣。
oracle的解決方法:首先,新增一個字段,將要修改列的數據update給新增字段,然後清空修改列的數據,修改該列,將新增字段的數據再update給修改列,刪除新增字段即可。
參考文檔:https://blog.csdn.net/u014427391/article/details/83046006
注意:oracle進行分組查詢統計,可先分組,再進行表關聯查詢,得到所有信息。
例如:查詢各部門中那些人工資最高(先分組查詢出部門最高的工資,將查詢結果作爲一個結果表,進行表關聯查詢,得到關聯信息,查詢出結果。
select ename, sal from emp
join ( select max(sal) max_sal ,deptno from emp group by deptno) t
on (emp.sal = t.max_sal and emp.deptno = t.deptno)
二、常用函數講解
常用函數參考文檔:https://blog.csdn.net/weixin_39805338/article/details/81002980
參考文檔:https://www.jellythink.com/archives/351
(一)聚合函數:(處理多行數據並返回一個結果)
max() min()可以適用於字符,數值,日期類型
sum()avg()適用於數值類型
count()統計表達式不爲null的行數。
注意:在使用聚合函數配合分組函數查詢數據時,如果查詢聚合函數使用以外的屬性(字段)時,會出現錯誤,因爲無法保證查詢結果的單一性,可能出現過個結果,例如,查詢各部門中薪水最高的員工姓名,select ename,max(sal)時,結果可能存在多個即多人的薪水一樣,都是最高。因此,當需要查詢多個字段值時,需要進行關聯查詢,將多個字段組合成一張虛表,進行查詢。
(二)單行函數(接受一個數據,輸出一個數據)
大小寫相關:lower(字段名):小寫 upper(字段名):大寫 initcap(字段名):首字母大寫,其他小寫
trim(字符串,要刪除的字符):刪除字符
rpad(字符串,字符長度,要添加的字符):字符串小於字符長度時,缺少的字符用要添加的字符在右邊來補充。lpad():在左邊來補充。
substr(字段名,開始位置,截取長度):截取字符串
instr(字符串,要搜索的字符串,開始搜索的位置,第幾次出現):搜索字符串,返回字符串第一次出現的位置。
注意:substr()和instr()的默認開始位置是從1,和數組區分開
concat(字符串,字符串):連接兩個字符串
replace(字段名,指定字符,替換字符):替換字符串
select replace('adsds','dsds','pple') from dual; 輸出結果:apple
(三)空值轉換函數
nvl(字段名,0):如果字段的值爲null,就用0來代替
nvl2(字段名,0,1):爲空用1代替,不爲空用0代替 select nvl2(null,0,1) from dual; 輸出結果爲1
空值轉換函數用於算數計算時,會常用:因爲任何含有空值(null)的算術表達式的值都爲空(null),需要將null轉換爲0即可。
(四)數值函數
round(x[,y])
【功能】返回四捨五入後的值
【參數】x,y,數字型表達式,如果y不爲整數則截取y整數部分,如果y>0則四捨五入爲y位小數,如果y小於0則四捨五入到小數點向左第y位。
【返回】數字
【示例】 select round(5555.6666,2.1),round(5555.6666,-2.6),round(5555.6666) from dual;
返回: 5555.67 , 5600 , 5556
trunc(數字):去除小數,不會四捨五入。
trunc(x[,y])
【功能】返回x按精度y截取後的值
【參數】x,y,數字型表達式,如果y不爲整數則截取y整數部分,如果y>0則截取到y位小數,如果y小於0則截取到小數點向左第y位,小數前其它數據用0表示。
【返回】數字
【示例】 select trunc(5555.66666,2.1),trunc(5555.66666,-2.6),trunc(5555.033333) from dual;
返回:5555.66 5500 5555
mod(數字,數字):求餘數 select mod(2,1) from dual; 輸出結果爲:0
5、日期函數
sysdate:系統當前日期 select sysdate from dual; 輸出結果:20-9月 -17
6、轉換函數
to_char(number或者date,‘格式’):將數字或者日期轉換爲指定格式的字符。
其中:L:表示本地貨幣符(大小寫不敏感) $:美元符會直接顯示 0和9:表示強制佔位符,其中0:表示高位無數字時,用0代替佔位。 ,:表示千位指示符
年:year,YYYY,yyyy (大小寫不敏感) 月:month,mm 日:DD 星期幾:DAY,DY,D(星期幾排序中的數字)
select to_char(1000,'l999,999') from dual; 輸出結果:¥1,000
select to_char(sysdate,'yyyy.mm.dd') from dual; 輸出結果爲:2017.09.20
to_date('字符串’,‘格式’):將指定格式的字符串轉換爲數據庫中的默認日期格式
select to_date('2017.2.21','yyyy-mm-dd') from dual; 輸出結果爲:21-2月 -17
to_number('字符串‘ [ ,'格式' ]):將指定格式的字符串轉換爲數字
<span style="color:#ff0000">add_months(日期x, 數字y)用於計算x加上y個月的結果。如果y是負數,就從x中減去y個月.</span>
例子:add_months(to_date('30-Nov-1961','d-mon-yyyy'),1) 返回 31-Dec-1961
注:從30調整爲31,爲了保持都是對應最後一天。
7、decode()函數,用法類似於if-else
格式:decode(條件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值)
如果條件和值1相同,返回值1,如果條件和值2相同,返回值2,其他遞推
decode(字段或字段的運算,值1,值2,值3)
這個函數運行的結果是,當字段或字段的運算的值等於值1時,該函數返回值2,否則返回值3;當然值1,值2,值3也可以是表達式
(五)分析函數(over partition by)和 分組函數(group by)
分析函數參考文檔:https://blog.csdn.net/myflysun/article/details/70477204
1、開窗函數:
開窗函數參考文檔:https://www.cnblogs.com/zhaoshujie/p/9594676.html
開窗函數格式:over(選項),選項包括:分組子句(partition by), 排序子句(order by), 窗口子句(rows或者range)。它用於爲行定義一個窗口(這裏的窗口是指運算將要操作的行的集合)。
(1)RANGE 是邏輯窗口,是指定當前行對應值的範圍取值,列數不固定,只要行值在範圍內,對應列都包含在內。
(2)ROWS 是物理窗口,即根據order by 子句排序後,取的前N行及後N行的數據計算。(與當前行的值無關,只與排序後的行號相關)。
(3)窗口子句指定範圍參數:第一行是 unbounded preceding;當前行是 current row;最後一行是 unbounded following。
例如:rows BETWEEN unbounded preceding AND CURRENT ROW 表示指定取值範圍爲 當前行與當前行前面的所有行的值。
實例:select ename,deptno,sal,sum(sal) over(partition by deptno order by sal rows BETWEEN unbounded preceding AND CURRENT ROW) from emp;
詳解操作:表示在對sal求和時,是按照當前行和前面所有的行依次累加求和,例如:第一行和爲1,第二行和爲:1+2=3,第三行和爲:1+2+3=6,依次類推。
注意:開窗函數也可以配合聚合函授進行查詢。
實例:rows BETWEEN 1 preceding AND 2 following 表示指定取值範圍爲 當前行與前一行和後兩行的值。
詳解:第一行和爲:1+0+2+3=6,第二行爲2+1+3+4=10,依次類推。
(4)over 子句可以與聚合函數結合使用(max、min、sum、avg、count等)
窗口子句中我們經常用到指定第一行,當前行,最後一行這樣的三個屬性:
第一行是 unbounded preceding,
當前行是 current row,
最後一行是 unbounded following,
例如:
last_value(sal) over(partition by deptno
order by sal
rows between unbounded preceding and unbounded following)
注意:over (partition by 字段名)也具有分組的功能,配合聚合函數使用,但是會輸出同組中的每一條記錄。要同group by 區分開
2、分組函數:group by 字段名
group by是對檢索結果的保留行進行單純分組,一般總愛和聚合函數一塊用例如AVG(),COUNT(),max(),main()等一塊用。
group by將分組後的數據看做一個整體,和聚合函數配合使用,每組返回一條結果數據
例子:
表a,內容如下:
B C D
02 02 1
02 03 2
02 04 3
02 05 4
02 01 5
02 06 6
02 07 7
02 03 5
02 02 12
02 01 2
02 01 23
select b,c,sum(d) e from a group by b,c
得到:
B C E
02 01 30
02 02 13
02 03 7
02 04 3
02 05 4
02 06 6
02 07 7
而使用分析函數得到的結果是:
SELECT b, c, d, SUM(d) OVER(PARTITION BY b,c ORDER BY d) e FROM a
B C E
02 01 2
02 01 7
02 01 30
02 02 1
02 02 13
02 03 2
02 03 7
02 04 3
02 05 4
02 06 6
02 07 7
結果不一樣,這樣看還不是很清楚,我們把d的內容也顯示出來就更清楚了:
SELECT b, c, d,SUM(d) OVER(PARTITION BY b,c ORDER BY d) e FROM a
B C D E
02 01 2 2 d=2,sum(d)=2
02 01 5 7 d=5,sum(d)=7
02 01 23 30 d=23,sum(d)=30
02 02 1 1 c值不同,重新累計
02 02 12 13
02 03 2 2
02 03 5 7
02 04 3 3
02 05 4 4
02 06 6 6
02 07 7 7
(六)rank() over,dense_rank(),row_number() 的區別
①row_number() over(partition by 字段名):
row_number函數返回一個唯一的值,當碰到相同數據時,排名按照記錄集中記錄的順序依次遞增。例如:1234
②dense_rank() over(partition by 字段名):
dense_rank函數返回一個唯一的值,當碰到相同數據時,此時所有相同數據的排名都是一樣的。例如:1223
③rank() over(partition by 字段名):
rank函數返回一個唯一的值,當碰到相同的數據時,此時所有相同數據的排名是一樣的,同時會在最後一條相同記錄和下一條不同記錄的排名之間空出排名。例如:1224(注意沒有3,因爲3被空出來了)