oracle之DQL,DML以及常用函式(重點)
注意: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)
(一)select
select * [distinct ] 列 as 列別名 from 表名
where 條件 //對每條資料進行過濾
group by 列 //對過濾後的資料進行分組
Having 分組條件 //對分組進行限制
order by 列 [asc(預設升序) | desc (降序)] ;
1、聚合函式:(接受一組資料,輸出一個數據)
max() min()可以適用於字元,數值,日期型別
sum()avg()適用於數值型別
count()統計表達式不為null的行數。
2、給列或者表起別名也可以省略as
3、比較運算子:其中不等於有三種表示<> ,!=,^= 第一種用的多即<>.
[not] between and 介於二者之間 【not】 like 匹配字串 %:表示0或多個字元 _:表示一個字元
is 【not】null 判斷是否為null 【not】in 匹配其中的數值
4、字元和日期用單引號定界,日期格式比較敏感
(二)update
update 表名 set column1= value1, column2=Value2 where column=Value;
(三)delete
delete from 表名 where column=Value;
與truncate table 表名 區分開
1、 Truncate比Delete所用的事務日誌空間更少:
DELETE 是一行一行操作,並且把記錄都存進日誌檔案(說明一下,無論任何恢復模式,都會記錄日誌)。而TRUNCATE操作,是對一個頁操作,在日誌中,僅僅記錄釋放頁面的這個動作,而不記錄每一行。
2、TRUNCATE TABLE:刪除內容、釋放空間但不刪除定義。3、DELETE TABLE:刪除內容不刪除定義,不釋放空間(會有空頁)。
(四)insert
第一種形式無需指定要插入資料的列名,只需提供被插入的值即可:
INSERT INTO table_nameVALUES (value1,value2,value3,...);
第二種形式需要指定列名及被插入的值:
INSERT INTO table_name (column1,column2,column3,...)VALUES (value1,value2,value3,...);
(五)常用函式
1、單行函式(接受一個數據,輸出一個數據)
大小寫相關:lower(欄位名):小寫 upper(欄位名):大寫 initcap(欄位名):首字母大寫,其他小寫
trim(字串,要刪除的字元):刪除字元
rpad(字串,字元長度,要新增的字元):字串小於字元長度時,缺少的字元用要新增的字元在右邊來補充。lpad():在左邊來補充。
substr(欄位名,開始位置,擷取長度):擷取字串
instr(字串,要搜尋的字串,開始搜尋的位置,第幾次出現):搜尋字串,返回字串第一次出現的位置。
注意:substr()和instr()的預設開始位置是從1,和陣列區分開
concat(字串,字串):連線兩個字串
replace(欄位名,指定字元,替換字元):替換字串
select replace('adsds','dsds','pple') from dual; 輸出結果:apple
2、空值轉換函式
nvl(欄位名,0):如果欄位的值為null,就用0來代替
nvl2(欄位名,0,1):為空用1代替,不為空用0代替 select nvl2(null,0,1) from dual; 輸出結果為1
空值轉換函式用於算數計算時,會常用:因為任何含有空值(null)的算術表示式的值都為空(null),需要將null轉換為0即可。
3、數值函式
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
4、日期函式
sysdate:系統當前日期 select sysdate from dual; 輸出結果:20-9月 -17
5、轉換函式
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('字串‘ [ ,'格式' ]):將指定格式的字串轉換為數字
add_months(日期x, 數字y)用於計算x加上y個月的結果。如果y是負數,就從x中減去y個月.
例子:add_months(to_date('30-Nov-1961','d-mon-yyyy'),1) 返回 31-Dec-1961
注:從30調整為31,為了保持都是對應最後一天。
6、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)
1、分析函式:over (partition by 欄位名)
分析函式帶有一個開窗函式over(),包含三個分析子句:分組(partition by), 排序(order by), 視窗(rows) ,他們的使用形式如下:over(partition by xxx order by yyy rows between zzz)。
over 子句可以與聚合函式結合使用(max、min、sum、avg、count等)
注:視窗子句在這裡我只說rows方式的視窗,range方式和滑動視窗也不提
視窗子句中我們經常用到指定第一行,當前行,最後一行這樣的三個屬性:
第一行是 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