oracle之數據查詢語句和數據操作語句以及常用函數和分析函數(重點)

                                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被空出來了)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章