1. 程式人生 > >Oracle語言分類、資料型別、資料型別轉換、常用函式、集合操作、子查詢

Oracle語言分類、資料型別、資料型別轉換、常用函式、集合操作、子查詢

 SQL分類

SQL(Structure Query Language)語言是資料庫的核心語言。

SQL語言共分為四大類:資料定義語言DDL,資料操縱語言DML,資料查詢語言DQL,資料控制語言DCL。

1. 資料定義語言DDL
資料定義語言DDL用來建立資料庫中的各種物件-----表、檢視、索引、同義詞、聚簇等如:
CREATE TABLE/VIEW/INDEX/SYN/CLUSTER
DDL操作是隱性提交的!不能rollback 

2 .資料操縱語言DML
資料操縱語言DML主要有三種形式:
1) 插入:INSERT
2) 更新:UPDATE
3) 刪除:DELETE

3. 資料查詢語言DQL
資料查詢語言DQL基本結構是由SELECT子句,FROM子句,WHERE子句組成的查詢塊:
SELECT <欄位名錶>
FROM <表或檢視名>
WHERE <查詢條件>

4. 資料控制語言DCL
資料控制語言DCL用來授予或回收訪問資料庫的某種特權,並控制資料庫操縱事務發生的時間及效果,對資料庫實行監視等。如:
1) GRANT:授權。

 資料型別

-- 1、字串型別
-- 定長型別:指輸入的欄位值小於該欄位的限制長度,但是實際儲存資料時,會先自動向右補足空格
-- 優點:儲存/查詢效率高
-- 代表:CHAR型別 CHAR(size [BYTE | CHAR]),預設按位元組儲存,如果指定按字元儲存就按字元儲存
-- 舉例:CHAR_OLD預設,CHAR_NEW指定為字元儲存
CREATE TABLE CHAR_TEST(
       CHAR_OLD CHAR(10),
       CHAR_NEW CHAR(10 CHAR)
);
-- 插入
INSERT INTO CHAR_TEST(CHAR_OLD,CHAR_NEW) SELECT 'ABCDEFGHIJ','我要五個字我要五個字' FROM DUAL;
COMMIT;
SELECT * FROM CHAR_TEST;
-- 反過來再試試?
INSERT INTO CHAR_TEST(CHAR_OLD,CHAR_NEW) SELECT '我要五個字我要五個字','ABCDEFGHIJ' FROM DUAL;
-- CHAR_OLD的值太大(實際值:31,最大值10),因為在oracle中,如果NLS_CHARACTERSET為AL32UTF8,一個漢字佔用三個位元組

-- 變長型別:指輸入的欄位值小於該欄位的限制長度,不會自動向右補足空格至最大長度
-- 優點:節省資料塊空間
-- 代表:VARCHAR和VARCHAR2,兩者沒有太大區別,VARCHAR2為ORACLE特有的資料型別,一般建議使用VARCHAR2
-- 舉例:CHAR_OLD預設,CHAR_NEW指定為字元儲存

-- 2、數字型別
-- NUMBER(P,S):P精度,即長度,S為小數位數
-- INTEGER:NUMBER的子型別,相當於NUMBER(38,0),用於儲存整數,如果插入小數,會四捨五入
-- 舉例
create table integer_test(
       integer_col integer,
       number_col number(38,2)
);
insert into integer_test(integer_col,number_col) select 11,11 from dual;
insert into integer_test(integer_col,number_col) select 11.11,11.11 from dual;
insert into integer_test(integer_col,number_col) select 11.51,11.51 from dual;
commit;
select * from integer_test;
--------------------- 
-- FLOAT:NUMBER的子型別,浮點型
-- FLOAT(n):n表示精度,但是他的長度不好控制,建議用NUMBER或者DOUBLE
alter table integer_test add float_col float(7);

insert into integer_test(integer_col,number_col,float_col) select 11.11,11.11,11.11 from dual;
insert into integer_test(integer_col,number_col,float_col) select 11.51,11.51,11.51 from dual;
select * from integer_test;
--------------------- 
-- 3、日期型別
-- DATE:日期資料型別可以儲存日期和時間資訊
-- TIMESTAMP:時間戳可以包含小數秒,帶小數秒的時間戳在小數點右邊最多可以保留9位
-- DATE型別可以加一個數字,這個數字代表的是天數,表示多少天后的日期
-- 舉例
select sysdate + 30 as "30天后的日期" from dual;
-- DATE型別可以相減,表示兩個時間差
-- 舉例
select trunc((sysdate - hiredate)/365, 2) as "工作年限" from emp;
select to_char((sysdate - hiredate)/365, '9999.99') as "工作年限" from emp;
-- PS:trunc函式,保留幾位小數,但是如果最後是0,則省略,如果要求格式工整,可用to_char(char,'99.99')
--------------------- 
-- 四、LOB型別
-- CLOB:用於儲存單位元組和多位元組字元資料
-- BLOB:用於儲存二進位制資料

-- 五、RAW和LONG RAW型別
-- 1、LONG:它儲存變長字串,最多達2G的字元資料(2GB是指2千兆位元組, 而不是2千兆字元)
-- 與VARCHAR2 或CHAR 型別一樣,儲存在LONG 型別中的文字要進行字符集轉換
-- ORACLE建議開發中使用CLOB替代LONG型別。支援LONG 列只是為了保證向後相容性。CLOB型別比LONG型別的限制要少得多。
-- 官方給出的具體限制如下
--    一個表中只有一列可以為LONG型。
--    LONG列不能定義為主鍵或唯一約束,
--    不能建立索引
--    LONG資料不能指定正則表示式。
--    函式或儲存過程不能接受LONG資料型別的引數。
--    LONG列不能出現在WHERE子句或完整性約束(除了可能會出現NULL和NOT NULL約束)

-- 2、RAW:用於儲存二進位制或字元型別資料,變長二進位制資料型別

-- 六、ROWID和UROWID
--------------------- 

資料型別轉換

三大型別轉換
oracle中三大型別與隱式資料型別轉換 
(1)varchar2變長/char定長–>number,例如:’123’->123 
(2)varchar2/char–>date,例如:’25-4月-15’->’25-4月-15’ 
(3)number—->varchar2/char,例如:123->’123’ 
(4)date——>varchar2/char,例如:’25-4月-15’->’25-4月-15’

oracle如何隱式轉換: 
1)=號二邊的型別是否相同 
2)如果=號二邊的型別不同,嘗試的去做轉換 
3)在轉換時,要確保合法合理,否則轉換會失敗,例如:12月不會有32天,一年中不會有13月
--------------------- 

1.varchar轉為number,用 to_number(列名): 
select to_number(t.create_user) from 表名 t; 
2.number轉為varchar,用 to_char(列名): 
select to_char(t.user_role_id) from 表名 t; 
3.date轉為varchar型別,用 to_char(列名,想要的日期格式): 
select to_char(t.create_date,’yyyy-mm-dd’) 重點內容from 表名 t 
4.varchar型別轉date,用 to_date(列名,想要的日期格式): 
insert into 表名 values(1,’lili’,to_date(‘2012-11-11’,’yyyy-mm-dd’)); 
5.CAST——型別轉換 
select cast(” as number) as a, ‘01’ as b from dual union 
select 2 as a, ‘02’ as b from dual;
--------------------- 
--1、查詢1980年12月17日入職的員工(方式一:日期隱示式轉換)
select * from emp where hiredate = '17-12月-80';

--2、使用to_char(日期,'格"常量"式')函式將日期轉成字串,顯示如下格式:2018 年 02 月 26 日 星期二
select to_char(sysdate,'yyyy" 年 "mm" 月 "dd" 日 "day') from dual;

--3、使用to_char(日期,'格式')函式將日期轉成字串,顯示如格式:2018-02-06今天是星期二 15:59:15
select to_char(sysdate,'yyyy-mm-dd"今天是"day hh24:mi:ss') from dual;
--或  顯示如格式:2018-02-06今天是星期二 3:59:55 下午
select to_char(sysdate,'yyyy-mm-dd"今天是"day HH12:MI:SS AM') from dual;

--4、使用to_char(數值,'格式')函式將數值轉成字串,顯示如下格式:$1,234
select to_char(1234,'$9,999') from dual;

--使用to_char(數值,'格式')函式將數值轉成字串,顯示如下格式:¥1,234
select to_char(1234,'L9,999') from dual;

--5、使用to_date('字串','格式')函式,查詢1980年12月17日入職的員工(方式二:日期顯式轉換)
select * from emp where hiredate = to_date('1980年12月17日','yyyy"年"mm"月"dd"日"');
--或
select * from emp where hiredate = to_date('1980#12#17','yyyy"#"mm"#"dd');
--或
select * from emp where hiredate = to_date('1980-12-17','yyyy-mm-dd');

--6、使用to_number('字串')函式將字串‘123’轉成數字123
select to_number('123') from dual;


--注意:
select '123' + 123 from dual;  --246
select '123' || 123 from dual; --123123
--------------------- 
SYSDATE	2009-6-16 15:25:10	 
TRUNC(SYSDATE)	2009-6-16	 
TO_CHAR(SYSDATE,'YYYYMMDD')	20090616	到日
TO_CHAR(SYSDATE,'YYYYMMDD HH24:MI:SS')	20090616 15:25:10	到秒
TO_CHAR(SYSTIMESTAMP,'YYYYMMDD HH24:MI:SS.FF3')	20090616 15:25:10.848	到毫秒
TO_CHAR(SYSDATE,'AD')	公元	 
TO_CHAR(SYSDATE,'AM')	下午	 
TO_CHAR(SYSDATE,'BC')	公元	 
TO_CHAR(SYSDATE,'CC')	21	 
TO_CHAR(SYSDATE,'D')	3	老外的星期幾
TO_CHAR(SYSDATE,'DAY')	星期二	星期幾
TO_CHAR(SYSDATE,'DD')	16	 
TO_CHAR(SYSDATE,'DDD')	167	 
TO_CHAR(SYSDATE,'DL')	2009年6月16日 星期二	 
TO_CHAR(SYSDATE,'DS')	2009-06-16	 
TO_CHAR(SYSDATE,'DY')	星期二	 
TO_CHAR(SYSTIMESTAMP,'SS.FF3')	10.848	毫秒
TO_CHAR(SYSDATE,'FM')	 	 
TO_CHAR(SYSDATE,'FX')	 	 
TO_CHAR(SYSDATE,'HH')	03	 
TO_CHAR(SYSDATE,'HH24')	15	 
TO_CHAR(SYSDATE,'IW')	25	第幾周
TO_CHAR(SYSDATE,'IYY')	009	 
TO_CHAR(SYSDATE,'IY')	09	 
TO_CHAR(SYSDATE,'J')	2454999	 
TO_CHAR(SYSDATE,'MI')	25	 
TO_CHAR(SYSDATE,'MM')	06	 
TO_CHAR(SYSDATE,'MON')	6月 	 
TO_CHAR(SYSDATE,'MONTH')	6月 	 
TO_CHAR(SYSTIMESTAMP,'PM')	下午	 
TO_CHAR(SYSDATE,'Q')	2	第幾季度
TO_CHAR(SYSDATE,'RM')	VI  	 
TO_CHAR(SYSDATE,'RR')	09	 
TO_CHAR(SYSDATE,'RRRR')	2009	 
TO_CHAR(SYSDATE,'SS')	10	 
TO_CHAR(SYSDATE,'SSSSS')	55510	 
TO_CHAR(SYSDATE,'TS')	下午 3:25:10	 
TO_CHAR(SYSDATE,'WW')	24	 
TO_CHAR(SYSTIMESTAMP,'W')	3	 
TO_CHAR(SYSDATE,'YEAR')	TWO THOUSAND NINE	 
TO_CHAR(SYSDATE,'YYYY')	2009	 
TO_CHAR(SYSTIMESTAMP,'YYY')	009	 
TO_CHAR(SYSTIMESTAMP,'YY')	09

TO_CHAR 是把日期或數字轉換為字串
TO_DATE 是把字串轉換為資料庫中得日期型別轉換函式
TO_NUMBER 將字元轉化為數字

 TO_CHAR 
使用TO_CHAR函式處理數字 
TO_CHAR(number, '格式') 
TO_CHAR(salary,’$99,999.99’); 
使用TO_CHAR函式處理日期 
TO_CHAR(date,’格式’); 

 TO_NUMBER 
使用TO_NUMBER函式將字元轉換為數字 
TO_NUMBER(char[, '格式']) 

 TO_DATE 
使用TO_DATE函式將字元轉換為日期 
TO_DATE(char[, '格式']) 

 數字格式格式 
9 代表一個數字 
0 強制顯示0 
$ 放置一個$符 
L 放置一個浮動本地貨幣符 
. 顯示小數點 
, 顯示千位指示符 

 日期格式 
格式控制 描述 
YYYY、YYY、YY 分別代表4位、3位、2位的數字年 
YEAR 年的拼寫 
MM 數字月 
MONTH 月的全拼 
MON 月的縮寫 
DD 數字日 
DAY 星期的全拼 
DY 星期的縮寫 
AM 表示上午或者下午 
HH24、HH12 12小時制或24小時制 
MI 分鐘 
SS 秒鐘 
SP 數字的拼寫 
TH 數字的序數詞 

“特殊字元” 假如特殊字元 
HH24:MI:SS AM 15:43:20 PM 

日期例子:
SELECT TO_DATE('2006-05-01 19:25:34', 'YYYY-MM-DD HH24:MI:SS') FROM DUAL
SELECT TO_DATE('2006-05-01 19:25', 'YYYY-MM-DD HH24:MI') FROM DUAL
SELECT TO_DATE('2006-05-01 19', 'YYYY-MM-DD HH24') FROM DUAL
SELECT TO_DATE('2006-05-01', 'YYYY-MM-DD') FROM DUAL
SELECT TO_DATE('2006-05', 'YYYY-MM') FROM DUAL
SELECT TO_DATE('2006', 'YYYY') FROM DUAL

日期說明:
當省略HH、MI和SS對應的輸入引數時,Oracle使用0作為DEFAULT值。如果輸入的日期資料忽略時間部分,Oracle會將時、分、秒部分都置為0,也就是說會取整到日。

同樣,忽略了DD引數,Oracle會採用1作為日的預設值,也就是說會取整到月。

但是,不要被這種“慣性”所迷惑,如果忽略MM引數,Oracle並不會取整到年,取整到當前月。

注意:
1.在使用Oracle的to_date函式來做日期轉換時,可能會直覺地採用“yyyy-MM-dd HH:mm:ss”的格式作為格式進行轉換,但是在Oracle中會引起錯誤:“ORA 01810 格式程式碼出現兩次”。如:select to_date('2005-01-01 13:14:20','yyyy-MM-dd HH24:mm:ss') from dual;原因是SQL中不區分大小寫,MM和mm被認為是相同的格式程式碼,所以Oracle的SQL採用了mi代替分鐘。select to_date('2005-01-01 13:14:20','yyyy-MM-dd HH24:mi:ss') from dual;
2.另要以24小時的形式顯示出來要用HH24
select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual;//mi是分鐘
select to_char(sysdate,'yyyy-MM-dd HH24:mm:ss') from dual;//mm會顯示月份

常用函式 

1、數值型常用函式



 函式  返回值            樣例           顯示
ceil(n) 大於或等於數值n的最小整數  select ceil(10.6) from dual; 11

floor(n) 小於等於數值n的最大整數  select ceil(10.6) from dual; 10

mod(m,n) m除以n的餘數,若n=0,則返回m select mod(7,5) from dual; 2

power(m,n) m的n次方         select power(3,2) from dual; 9

round(n,m) 將n四捨五入,保留小數點後m位  select round(1234.5678,2) from dual; 1234.57

sign(n) 若n=0,則返回0,否則,n>0,則返回1,n<0,則返回-1 select sign(12) from dual; 1

sqrt(n) n的平方根         select sqrt(25) from dual ; 5

2、常用字元函式

initcap(char) 把每個字串的第一個字元換成大寫  select initicap('mr.ecop') from dual; Mr.Ecop

lower(char) 整個字串換成小寫         select lower('MR.ecop') from dual; mr.ecop

replace(char,str1,str2) 字串中所有str1換成str2 select replace('Scott','s','Boy') from dual; Boycott

substr(char,m,n) 取出從m字元開始的n個字元的子串  select substr('ABCDEF',2,2) from dual; CD

length(char) 求字串的長度    select length('ACD') from dual; 3

|| 並置運算子    select 'ABCD'||'EFGH' from dual; ABCDEFGH

3、日期型函式



sysdate 當前日期和時間 select sysdate from dual;

last_day  本月最後一天 select last_day(sysdate) from dual;

add_months(d,n) 當前日期d後推n個月 select add_months(sysdate,2) from dual;

months_between(d,n) 日期d和n相差月數 select months_between(sysdate,to_date('20020812','YYYYMMDD')) from dual;

next_day(d,day) d後第一週指定day的日期 select next_day(sysdate,'Monday') from dual;

day 格式  有  'Monday' 星期一  'Tuesday' 星期二

'wednesday'  星期三   'Thursday' 星期四    'Friday' 星期五

'Saturday' 星期六   'Sunday' 星期日

4、特殊格式的日期型函式

Y或YY或YYY 年的最後一位,兩位,三位 select to_char(sysdate,'YYY') from dual;

Q 季度,1-3月為第一季度    select to_char(sysdate,'Q') from dual;

MM  月份數           select to_char(sysdate,'MM') from dual;

RM 月份的羅馬錶示 select to_char(sysdate,'RM') from dual; IV

month 用9個字元表示的月份名 select to_char(sysdate,'month') from dual;

ww 當年第幾周         select to_char(sysdate,'ww') from dual;

w 本月第幾周         select to_char(sysdate,'w') from dual;

DDD 當年第幾天,一月一日為001 ,二月一日032 select to_char(sysdate,'DDD') from dual;

DD 當月第幾天 select to_char(sysdate,'DD') from dual;

D 周內第幾天 select to_char(sysdate,'D') from dual; 如 sunday

DY 周內第幾天縮寫       select to_char(sysdate,'DY') from dual; 如 sun

hh12 12小時制小時數       select to_char(sysdate,'hh12') from dual;

hh24 24小時制小時數       select to_char(sysdate,'hh24') from dual;

Mi 分鐘數            select to_char(sysdate,'Mi') from dual;

ss 秒數             select to_char(sysdate,'ss') from dual;

select to_char(sysdate,'YYYY-MM-DD HH:24:mi:ss') from dua;

to_number() 將合法的數字字串 select to_number('88877') from dual; 88877

to_char() 將數字轉換為字串  select to_char(88877) from dual; '88877'

set serveroupt on;

dbms_output.put_line('hello world')

set heading off 由於正在建立資料檔案,不需要表頭

set pagesize 0 不需要分頁

set linesize 80 設定行的最大尺寸

set echo off 告訴sql plus 在執行語句時,不要回顯語句

set feedback off 禁止sql plus 顯示有多少滿足查詢的行被檢索到

col sales format 999,999,999

append 新增文字到當前行尾

change/old/new/ 在當前行用新的文字代替舊的文字

 change/text 從當前行刪除wenb

 del 刪除當前行

 input text  在當前行之後新增一行

 list 顯示緩衝區中的所有行

 list n 顯示緩衝區中的第n行

list m n 顯示m到n

5、字元函式


--------------------------------------------------------------------------------

字元函式主要用於修改字元列。這些函式接受字元輸入,返回字元或數字值。Oracle 提供的一些字元函式如下。

1. CONCAT (char1, char2)

返回連線“char2”的“char1”。

示例  SELECT CONCAT( CONCAT(ename, ' is a '), job) FROM emp;

2. INITCAP(string)

將“string”的字元轉成大寫。

示例 Select INITCAP(ename) from emp;

3. LOWER (string)

將“string”轉成小寫。

示例 Select LOWER(ENAME) from emp;

4. LPAD(char1,n [,char2])

返回“char1”,左起由“char2”中的字元補充到“n”個字元長。如果“char1”比“n”長,則函式返回“char1”的前“n”個字元。

示例 SELECT LPAD(ename,15,'*') FROM emp;

5. LTRIM(string,trim_set)

從左邊刪除字元,此處“string”是資料庫的列,或者是字面字串,而“trim_set” 是我們要去掉的字元的集合。

示例 SELECT LTRIM('abcdab','a') FROM DUAL;

6. REPLACE(string, if, then)

用 0 或其他字元代替字串中的字元。“if”是字元或字串,對於每個出現在“string”中的“if”,都用“then”的內容代替。

示例 SELECT REPLACE('JACK and JUE','J','BL') FROM DUAL;

7. RPAD(char1, n [,char2])

返回“char1”,右側用“char2”中的字元補充到“n”個字元長。如果 “char1”比“n” 長,則函式返回“char1”的前“n”個字元。

示例 SELECT RPAD(ename,15,'*') FROM emp;

8. RTRIM(string,trim_set)

從右側刪除字元,此處“string”是資料庫的列,或者是字面字串,而“trim_set” 是我們要去掉的字元的集合。

示例 SELECT RTRIM('abcdef', 'f') FROM DUAL;

9. SOUNDEX(char)

返回包含“char”的表意字元的字串。它允許比較英語中拼寫不同而發音類似的字。

示例 SELECT ename FROM emp

WHERE SOUNDEX(ename) = SoUNDEX('SMYTHE');

10. SUBSTR(string, start [,count])

返回“string”中擷取的一部分。該命令擷取“string”的一個子集,從“start”位置開始,持續“count”個字元。如果我們不指定“count”,則從“start”開始擷取到“string”的尾部。

示例 SELECT SUBSTR('ABCDEFGIJKLM',3,4) FROM DUAL;

11. TRANSLATE(string, if, then)

“if”中字元的位置,並檢查“then”的相同位置,然後用該位置的字元替換 “string”中的字元。

示例 SELECT TRANSLATE(ename,'AEIOU', 'XXXXX') FROM emp;

12. UPPER(string)

返回大寫的“string”。

示例 SELECT UPPER('aptech computer education') FROM dual;

13. ASCII(string)

該命令是“American Standard Code for Information Interchange”的縮寫。它是使用數字表示可列印字元的基本規則。該函式返回 “string”中第一個(最左邊)字元的 ASCII 值。

示例 SELECT ASCII('APTECH') from dual;

14. INSTR (string, set[, start[, occurrence] ] )

該命令“string”中從“start”位置開始查詢字元集合的位置,再查詢“set”出現的第一次、第二次等等的“occurrence”(次數)。“start”的值也可以是負數,代表從字串結尾開始向反方向搜尋。該函式也用於數字和日期資料型別。

示例 SELECT INSTR('aptech is aptech','ap',1,2) FROM DUAL;

15. LENGTH(string)

返回“string”的長度值。

示例 SELECT ename, LENGTH(ename) FROM emp 

WHERE empno = 7698;
--------------------- 
1.模糊查詢like
%表示零或多個字元
_表示一個字元
對於特殊符號可以使用ESCAPE識別符號來查詢
select * from emp where ename like '%*_%'escape'*';
上面的escape表示*後面的字元不被當作特殊字元處理,就是普通的'_'符。

2.字元函式的使用
Upper 將字串轉為大寫
	select Upper('aabbcc') from dual;
	select * from emp where ename=UPPER('smith');
	
	Lower 將字串轉為小寫
	select Lower('AABBCC') from dual;
	select * from emp where ename=LOWER('SMITH');
	
	initcap 返回字串並將首字母轉為大寫
	select initcap(ename) from emp;
	
	Concat 將後一個字串連線到前一個字串的尾部
	select concat('a','b') from dual;
	select 'a' || 'b' from dual;
	
	Substr 返回擷取的字串
	Substr(字串,擷取開始位置,擷取長度)
	substr('Hello World',0,1) --返回結果為 'H'  *從字串第一個字元開始擷取長度為1的字串
	substr('Hello World',1,1) --返回結果為 'H'  *0和1都是表示擷取的開始位置為第一個字元
	substr('Hello World',2,4) --返回結果為 'ello'
	substr('Hello World',-3,3) --返回結果為 'rld' *用負數則從右邊開始數第幾個位置,擷取仍然是從左往右擷取
	測試:
	select substr('Hello World',-3,3) value from dual;
	
	length 返回字串的長度
	select length(ename) from emp;
	
	replace 替換欄位中指定的字串
	replace(原欄位,“原欄位舊內容“,“原欄位新內容“,)
	select replace(ename,'a','A') from emp;
	
	instr 在一個字串中查詢指定的字元,返回被查詢到的指定的字元的位置。 
	instr(sourceString,destString,start,appearPosition) 
	其中sourceString代表源字串; 
	destString代表要從源字串中查詢的子串; 
	start代表查詢的開始位置,這個引數可選的,預設為1; 
	appearPosition代表想從源字元中查找出第幾次出現的destString,這個引數也是可選的, 預設為1 
	如果start的值為負數,則代表從右往左進行查詢,但是位置資料仍然從左向右計算。 
	返回值為:查詢到的字串的位置。 
	select instr('Hello World','or') from dual; --返回結果:8 indexOf
	
	Lpad 
	lpad( string, padded_length, [ pad_string ] )
	string
  準備被填充的字串;
  padded_length
  填充之後的字串長度,也就是該函式返回的字串長度,如果這個數量比原字串的長度要短,lpad函式將會把字串擷取成從左到右的n個字元;
  pad_string
  填充字串,是個可選引數,這個字串是要貼上到string的左邊,如果這個引數未寫,lpad函式將會在string的左邊貼上空格。
	lpad('Smith',10,'*')  --返回結果:*****Smith
	
	Rpad
	rpad(string,padded_length,[pad_string])
	string
  被填充的字串
  padded_length
  字元的長度,是返回的字串的數量,如果這個數量比原字串的長度要短,rpad函式將會把字串擷取成從左到右的n個字元;
  pad_string
  是個可選引數,這個字串是要貼上到string的右邊,如果這個引數未寫,lpad函式將會在string的右邊貼上空格。
	Rpad('Smith',10,'*')  --返回結果為 Smith*****
	
	Trim 過濾掉首尾空格
	select trim(' Mr Smith ') from dual;--返回結果:Mr Smith

3.數值函式
Round
	將引數n按照n2指定的小數位進行四捨五入.不指定n2時預設n2為0,即近似到個位.如果第2個引數為負數時將對小數點左邊的數作四捨五入,回到左面的|n|+1位.
	select round(345.678,2) from dual; --四捨五入到百分位(小數點後第2位)
	select round(412,-2) from dual; --返回結果:400
	select round(412.313,-2) from dual; --返回結果:400
	
	Mod(n,n2)
	返回引數n除以引數n2時的餘數.
	select mod(10,2) from dual; -- 返回結果:0
	
	TRUNC(n,n2)	函式返回處理後的數值,其工作機制與ROUND函式極為類似,只是該函式不對指定小數前或後的部分做相應舍入選擇處理,而統統截去。
	第二個引數可以為負數,表示為小數點左邊指定位數後面的部分截去,即均以0記。與取整類似,比如引數為1即取整到十分位,如果是-1,則是取整到十位,以此類推。 
	TRUNC(89.985,2)=89.98
  TRUNC(89.985)=89
  TRUNC(89.985,-1)=80

4.日期函式
MONTHS_BETWEEN(DATE1,DATE2) 即MONTHS_BETWEEN(日期1,日期2)	函式返回兩個日期之間的月份數。如果兩個日期月份內天數相同,或者都是某個月的最後一天,返回一個整數.
	否則,返回數值帶小數,以每天1/31月來計算月中剩餘天數。如果日期1比日期2小 ,返回值為負數。
	例:months_between(to_date('1999.11.29','yyyy.mm.dd'), to_date('1998.11.29','yyyy.mm.dd')) 
    返回  12
	注:兩個引數均為同樣月份的29號,所以返回一整數。
	months_between(to_date('1999.11.29','yyyy.mm.dd'), to_date('1998.12.24','yyyy.mm.dd'))
    返回   13.16129
	注:兩個引數表示的日期不是同一天,所以返回帶小數的值。
	
	add_months(x,y)或者add_months(times,months)函式
	這個函式用於計算在時間x之上機上Y個月後的時間值,要是Y的值為負數的話就是在這個時間點之間的時間值(這個時間-Y個月)。
	如 select add_months(sysdate,-6) from dual; 
	該查詢的結果是當前時間半年前的時間
	select add_months(sysdate,6) from dual; 
	該查詢的結果是當前時間半年後的時間
	
	NEXT_DAY(date,char) 
	date引數為日期型, 
	char:為1~7或Monday/Mon~Sunday/  1-星期天 2-星期一 依次類推
	select next_day(sysdate,'星期日') from dual;  --返回結果:2016.12.4 16:01:52
	select next_day(sysdate,1) from dual;  --和上面相同結果
	
	LAST_DAY 函式返回指定日期對應月份的最後一天。
	select last_day(to_date('2016.11.29','yyyy.mm.dd')) from dual;
	返回結果:2016.11.30
	select last_day(to_date('2017.2.2','yyyy.mm.dd')) from dual;
	返回結果:2017.2.28

5.轉換函式
to_char(type, text)
	type:可以為timestamp、int、float、numeric格式
	text:轉換的模板。如:'yyyy-mm-dd hh24:mi:ss'
	
	to_date(type, text)
	用法同上相反
	select to_date('2005-01-01 13:14:20','yyyy-MM-dd HH24:mm:ss') from dual; 
	注:很多Java程式設計師也許會直接的採用“yyyy-MM-dd HH:mm:ss”的格式作為格式進行轉換,但是在Oracle中會引起錯誤:“ORA 01810 格式程式碼出現兩次”。
	原因是SQL中不區分大小寫,MM和mm被認為是相同的格式程式碼,所以Oracle的SQL採用了mi代替分鐘。
	
	to_number 將字串轉換為數字資料型別
	select to_number('12')+to_number('13') from dual;
	返回結果:15

6.通用函式
sign(n)
	取數字n的符號,大於0返回1,小於0返回-1,等於0返回0
 
	NVL(expr1,expr2)
	含義是:如果oracle第一個引數為空(null)那麼顯示第二個引數的值,如果第一個引數的值不為空,則顯示第一個引數本來的值。
	注:Oracle會把''轉化為null。但是'' 不等於' '。
	
	nvl2(expr1,expr2,expr3)
	如果 expr1 不是 null 值,則 nvl 函式返回 expr2 ,否則就返回 expr3 。引數可以返回任何資料型別的值,但是 expr2 和 expr3 不能是 LONG 型的資料型別。
	說明:若 expr2 和 expr3 的資料型別不同:
   	 (1)若 expr2 是字元資料,則Oracle資料庫在比較之前就會把 expr3 轉換成 expr2 的資料型別除非 expr3 是null。在 這種情況下,隱式資料轉換是不必要的。Oracle資料庫返回 VARCHAR2 資料型別到 expr2 的字符集。
    	(2) 若 expr2 是數值型,則Oracle資料庫決定哪個引數具有最高數值優先順序,並把另一個引數的資料型別隱式轉換成這種資料型別,並返回這種資料型別的資料。
	
	NULLIF(表示式1,表示式2)
	如果表示式1和表示式2相等則返回空值,如果表示式1和表示式2不相等則返回表示式1的結果。
	注意:表示式1和表示式2應該是相同資料型別或能隱含轉換成相同資料型別,表示式1不能用字元null,但''不報錯。
	
	COALESCE(表示式1,表示式2,...,表示式n)
	n>=2,此表示式的功能為返回第一個不為空的表示式,如果都為空則返回空值。
	注意:所有表示式必須為同一型別或者能轉換成同一型別。
	
	case 表示式和java中的switch 類似
	select empno,ename,sal,case deptno 
									when 10 then '財務部'
									when 20 then '開發部'
									when 30 then '行政部'
							else '未知部門'
							end dept_name
	from emp;	
 
	DECODE(value,if1,then1,if2,then2,if3,then3,...,else)
	表示如果value等於if1時,DECODE函式的結果返then1,...,如果不等於任何一個if值,則返回else。
	可以用函式或表示式來替代value,if,then,else從而作出一些更有用的比較。





集合操作 

--Oracle中的複合查詢
複合查詢:包含集合運算(操作)的查詢
常見的集合操作有:
union:    兩個查詢的並集(無重複行、按第一個查詢的第一列升序排序)
union all:兩個查詢的並集(有重複行)
intersect:兩個查詢的交集(無重複行、按第一個查詢的第一列升序排序)
minus:    兩個查詢的差集(無重複行、按第一個查詢的第一列升序排序),取第一張表有而第二張表沒有的所有記錄

由於union、intersect、minus存在排序,故而對sql效能的影響很大,建議少用。

--測試
create table t1 (id number,name varchar2(20));
create table t2 (id number,name varchar2(20));
insert into t1 values(1,'表1');
insert into t1 values(2,'表1');
insert into t1 values(3,'表1');
insert into t1 values(4,'表1');
insert into t1 values(5,'表1');
insert into t2 values(3,'表2');
insert into t2 values(4,'表2');
insert into t2 values(5,'表2');
insert into t2 values(6,'表2');
insert into t2 values(7,'表2');

--查詢t1和t2
SQL> select * from t1;
 
        ID NAME
---------- --------------------
表1
表1
表1
表1
表1

SQL> select * from t2;
 
        ID NAME
---------- --------------------
表2
表2
表2
表2
表2

--並集 
--1.union                
select id  from t1
union
select id from t2 ;

SQL> select id  from t1
 union
 select id from t2 ;
 
        ID
----------
         2
         4
         6
 
rows selected

--2.union all
select id  from t1 
union all
select id from t2;

SQL> select id  from t1
 union all
 select id from t2;
 
        ID
----------
         2
         4
         3
         5
         7
rows selected

--交集
select id  from t1 
intersect
select id from t2;

SQL> select id  from t1
 intersect
 select id from t2;
 
        ID
----------
         4

--差集
select id  from t1 
minus
select id from t2;

SQL> select id  from t1
 minus
 select id from t2;
 
        ID
----------
         2
------------------------------------
1、UION操作 
select empno, ename, job, deptno from emp where deptno=10 
union 
select empno, ename, job, deptno from emp; 
將兩個查詢結果合併在了一起,相同的結果不重複顯示。

2、UION ALL操作 
select empno, ename, job, deptno from emp where deptno=10 
union all 
select empno, ename, job, deptno from emp; 
將兩個查詢結果合併在了一起,所有的重複資料都會進行顯示。

3、INTERSECT操作 
select empno, ename, job, deptno from emp where deptno=10 
intersect 
select empno, ename, job, deptno from emp; 
返回相同的部分,屬於交集操作。

4、MINUS操作 
select empno, ename, job, deptno from emp 
minus 
select empno, ename, job, deptno from emp where deptno=10; 
返回了兩個集合的差集,用第一個查詢結果減去第二個查詢結果。

注:進行多表查詢的資料集合操作時,多個查詢結果返回的結構必須相同。
--------------------- 
Oracle查詢語句

select * from scott.emp ;



1.--dense_rank()分析函式(查詢每個部門工資最高前三名員工資訊)

select * from (select deptno,ename,sal,dense_rank() over(partition by deptno order by sal desc) a from scott.emp) where a<=3 order by deptno asc,sal desc ;

結果:



--rank()分析函式(執行結果與上語句相同)

select * from (select deptno,ename,sal,rank() over(partition by deptno order by sal desc) a from scott.emp ) where a<=3 order by deptno asc,sal desc ;

結果:



--row_number()分析函式(執行結果與上相同)

select * from(select deptno,ename,sal,row_number() over(partition by deptno order by sal desc) a from scott.emp) where a<=3 order by deptno asc,sal desc ;

--rows unbounded preceding 分析函式(顯示各部門的積累工資總和)

select deptno,sal,sum(sal) over(order by deptno asc rows unbounded preceding) 積累工資總和 from scott.emp ;

結果:



--rows 整數值 preceding(顯示每最後4條記錄的彙總值)

select deptno,sal,sum(sal) over(order by deptno rows 3 preceding) 每4彙總值 from scott.emp ;

結果:



--rows between 1 preceding and 1 following(統計3條記錄的彙總值【當前記錄居中】)

select deptno,ename,sal,sum(sal) over(order by deptno rows between 1 preceding and 1 following) 彙總值 from scott.emp ;

結果:



--ratio_to_report(顯示員工工資及佔該部門總工資的比例)

select deptno,sal,ratio_to_report(sal) over(partition by deptno) 比例 from scott.emp ;

結果:



--檢視所有使用者

select * from dba_users ;

select count(*) from dba_users ;

select * from all_users ;

select * from user_users ;

select * from dba_roles ;

--檢視使用者系統許可權

select * from dba_sys_privs ;

select * from user_users ;

--檢視使用者物件或角色許可權

select * from dba_tab_privs ;

select * from all_tab_privs ;

select * from user_tab_privs ;

--檢視使用者或角色所擁有的角色

select * from dba_role_privs ;

select * from user_role_privs ;

-- rownum:查詢10至12資訊

select * from scott.emp a where rownum<=3 and a.empno not in(select b.empno from scott.emp b where rownum<=9);

結果:



--not exists;查詢emp表在dept表中沒有的資料

select * from scott.emp a where not exists(select * from scott.dept b where a.empno=b.deptno) ;

結果:



--rowid;查詢重複資料資訊

select * from scott.emp a where a.rowid>(select min(x.rowid) from scott.emp x where x.empno=a.empno);

--根據rowid來分頁(一萬條資料,查詢10000至9980時間大概在0.03秒左右)

select * from scott.emp where rowid in(select rid from(select rownum rn,rid from(select rowid rid,empno from scott.emp order by empno desc) where rownum<10)where rn>=1)order by empno desc ;

結果:



--根據分析函式分頁(一萬條資料,查詢10000至9980時間大概在1.01秒左右)

select * from(select a.*,row_number() over(order by empno desc) rk from scott.emp a ) where rk<10 and rk>=1;

結果:



--rownum分頁(一萬條資料,查詢10000至9980時間大概在0.01秒左右)

select * from(select t.*,rownum rn from(select * from scott.emp order by empno desc)t where rownum<10) where rn>=1;

select * from(select a.*,rownum rn from (select * from scott.emp) a where rownum<=10) where rn>=5 ;

--left outer join:左連線

select a.*,b.* from scott.emp a left outer join scott.dept b on a.deptno=b.deptno ;

--right outer join:右連線

select a.*,b.* from scott.emp a right outer join scott.dept b on a.deptno=b.deptno ;

--inner join

select a.*,b.* from scott.emp a inner  join scott.dept b on a.deptno=b.deptno ;

--full join

select a.*,b.* from scott.emp a full join scott.dept b on a.deptno=b.deptno ;

select a.*,b.* from scott.emp a,scott.dept b where a.deptno(+)=b.deptno ;

select distinct ename,sal from scott.emp a group by sal having ;

select * from scott.dept ;

select * from scott.emp ;

--case when then end (交叉報表)

select ename,sal,case deptno when 10 then '會計部' when 20 then '研究部' when 30 then '銷售部' else '其他部門' end 部門 from scott.emp ;

結果:



select ename,sal,case when sal>0 and sal<1500 then '一級工資' when sal>=1500 and sal<3000 then '二級工資' when sal>=3000 and sal<4500 then '三級工資' else '四級工資' end 工資等級 from scott.emp order by sal desc ;

結果:



--交叉報表是使用分組函式與case結構一起實現

select 姓名,sum(case 課程 when '數學' then 分數 end)數學,sum(case 課程 when '歷史' then 分數 end)歷史 from 學生 group by 姓名 ;

--decode 函式

select 姓名,sum(decode(課程,'數學',分數,null))數學,sum(decode(課程,'語文',分數,null))語文,sum(decode(課程,'歷史','分數',null))歷史 from 學生 group by 姓名 ;

--level。。。。connect by(層次查詢)

select level,emp.* from scott.emp connect by prior empno = mgr order by level ;

結果:



--sys_connect_by_path函式

select ename,sys_connect_by_path(ename,'/') from scott.emp start with mgr is null connect by prior empno=mgr ;

結果:



--start with connect by prior 語法

select lpad(ename,3*(level),'')姓名,lpad(ename,3*(level),'')姓名 from scott.emp where job<>'CLERK' start with mgr is null connect by prior mgr = empno ;

--level與prior關鍵字

select level,emp.* from scott.emp start with ename='SCOTT' connect by prior empno=mgr;

select level,emp.* from scott.emp start with ename='SCOTT' connect by empno = prior mgr ;

結果:



--等值連線

select empno,ename,job,sal,dname from scott.emp a,scott.dept b where a.deptno=b.deptno and (a.deptno=10 or sal>2500);

結果:



--非等值連線

select a.ename,a.sal,b.grade from scott.emp a,scott.salgrade b where a.sal between b.losal and b.hisal ;

結果:



--自連線

select a.ename,a.sal,b.ename from scott.emp a,scott.emp b where a.mgr=b.empno ;

結果:



--左外連線

select a.ename,a.sal,b.ename from scott.emp a,scott.emp b where a.mgr=b.empno(+);

結果:



--多表連線

select * from scott.emp ,scott.dept,scott.salgrade where scott.emp.deptno=scott.dept.deptno and scott.emp.sal between scott.salgrade.losal and scott.salgrade.hisal ;

結果:



select * from scott.emp a join scott.dept b on a.deptno=b.deptno join scott.salgrade s on a.sal between s.losal and s.hisal where a.sal>1000;

select * from(select * from scott.emp a join scott.dept b on a.deptno=b.deptno where a.sal>1000) c join scott.salgrade s on c.sal between s.losal and s.hisal ;

--單行子查詢

select * from scott.emp a where a.deptno=(select deptno from scott.dept where loc='NEW YORK');

select * from scott.emp a where a.deptno in (select deptno from scott.dept where loc='NEW YORK');

結果:



--單行子查詢在 from 後

select scott.emp.*,(select deptno from scott.dept where loc='NEW YORK') a from scott.emp ;

--使用 in ,all,any 多行子查詢

--in:表示等於查詢出來的對應資料

select ename,job,sal,deptno from scott.emp where job in(select distinct job from scott.emp where deptno=10);

--all:表示大於所有括號中查詢出來的對應的資料資訊

select ename,sal,deptno from scott.emp where sal>all(select sal from scott.emp where deptno=30);

--any:表示大於括號查詢出來的其中任意一個即可(只隨機一個)

select ename,sal,deptno from scott.emp where sal>any(select sal from scott.emp where deptno=30);

--多列子查詢

select ename,job,sal,deptno from scott.emp where(deptno,job)=(select deptno,job from scott.emp where ename='SCOTT');

select ename,job,sal,deptno from scott.emp where(sal,nvl(comm,-1)) in(select sal,nvl(comm,-1) from scott.emp where deptno=30);

--非成對比較

select ename,job,sal,deptno from scott.emp where sal in(select sal from scott.emp where deptno=30) and nvl(comm,-1) in(select nvl(comm,-1) from scott.emp where deptno=30);

--其他子查詢

select ename,job,sal,deptno from scott.emp where exists(select null from scott.dept where scott.dept.deptno=scott.emp.deptno and scott.dept.loc='NEW YORK');

select ename,job,sal from scott.emp join(select deptno,avg(sal) avgsal,null from scott.emp group by deptno) dept on emp.deptno=dept.deptno where sal>dept.avgsal ;

create table scott.test(

       ename varchar(20),

       job varchar(20)

);

--drop table test ;

select * from scott.test ;

--Insert與子查詢(表間資料的拷貝)

insert into scott.test(ename,job) select ename,job from scott.emp ;

--Update與子查詢

update scott.test set(ename,job)=(select ename,job from scott.emp where ename='SCOTT' and deptno ='10');

--建立表時,還可以指定列名

create table scott.test_1(ename,job) as select ename,job from scott.emp ;

select * from scott.test_1 ;

--delete與子查詢

delete from scott.test where ename in('');

--合併查詢

--union語法(合併且去除重複行,且排序)

select ename,sal,deptno from scott.emp where deptno>10 union select ename,sal,deptno from scott.emp where deptno<30 ;

select a.deptno from scott.emp a union select b.deptno from scott.dept b ;

--union all(直接將兩個結果集合並,不排序)

select ename,sal,deptno from scott.emp where deptno>10 union all select ename,sal,deptno from scott.emp where deptno<30 ;

select a.deptno from scott.emp a union all select b.deptno from scott.dept b ;

--intersect:取交集

select ename,sal,deptno from scott.emp where deptno>10 intersect select ename,sal,deptno from scott.emp where deptno<30;

--顯示部門工資總和高於僱員工資總和三分之一的部門名及工資總和

select dname as 部門,sum(sal) as 工資總和 from scott.emp a,scott.dept b where a.deptno=b.deptno group by dname having sum(sal)>(select sum(sal)/3 from scott.emp c,scott.dept d where c.deptno=d.deptno);

結果:



--使用with得到以上同樣的結果

with test as (select dname ,sum(sal) sumsal  from scott.emp ,scott.dept where scott.emp.deptno=scott.dept.deptno group by dname) select dname as 部門,sumsal as 工資總和 from scott.test where sumsal>(select sum(sumsal)/3 from scott.test);

結果:



--分析函式

select ename,sal,sum(sal) over(partition by deptno order by sal desc) from scott.emp ;

--rows n preceding(視窗子句一)

select deptno,sal,sum(sal) over(order by sal rows 5 preceding) from scott.emp ;

結果:



--rum(..) over(..)..

select sal,sum(1) over(order by sal) aa from scott.emp  ;

select deptno,ename,sal,sum(sal) over(order by ename) 連續求和,sum(sal) over() 總和,100*round(sal/sum(sal) over(),4) as 份額 from scott.emp;

結果:



select deptno,ename,sal,sum(sal) over(partition by deptno order by ename) 部門連續求和,sum(sal) over(partition by deptno) 部門總和,100*round(sal/sum(sal) over(),4) as 總份額 from scott.emp;

結果:



select deptno,sal,rank() over (partition by deptno order by sal),dense_rank() over(partition by deptno order by sal) from scott.emp order by deptno ;

結果;



select * from (select rank() over(partition by 課程 order by 分數 desc) rk,分析函式_rank.* from 分析函式_rank) where rk<=3 ;

--dense_rank():有重複的數字不跳著排列

--row_number()

select deptno,sal,row_number() over(partition by deptno order by sal) rm from scott.emp ;

結果:



--lag()和lead()

select deptno,sal,lag(sal) over(partition by deptno order by sal) 上一個,lead(sal) over(partition by deptno order by sal) from scott.emp ;

結果:



--max(),min(),avg()

select deptno,sal,max(sal) over(partition by deptno order by sal)最大,min(sal) over(partition by deptno order by sal)最小,avg(sal) over(partition by deptno order by sal)平均 from scott.emp ;

結果:



--first_value(),last_value()

select deptno,sal,first_value(sal) over(partition by deptno)最前,last_value(sal) over(partition by deptno )最後 from scott.emp ;

結果:



--分組補充 group by grouping sets

select deptno ,sal,sum(sal) from scott.emp group by grouping sets(deptno,sal);

select null,sal,sum(sal) from scott.emp group by sal union all select deptno,null,sum(sal) from scott.emp group by deptno ;

結果:



--rollup

select deptno,job,avg(sal) from scott.emp group by rollup(deptno,job) ;

--理解rollup等價於

select deptno,job,avg(sal) from scott.emp group by deptno,job union select deptno ,null,avg(sal) from scott.emp group by deptno union select null,null,avg(sal) from scott.emp ;

結果:



select deptno,job,avg(sal) a from scott.emp group by cube(deptno,job) ;

--理解CUBE

select deptno,job,avg(sal) from scott.emp group by cube(deptno,job) ;

--等價於

select deptno,job,avg(sal) from scott.emp group by grouping sets((deptno,job),(deptno),(job),());

結果:



--查詢工資不在1500至2850之間的所有僱員名及工資

select ename,sal from scott.emp where sal not in(select sal from scott.emp where sal between 1500 and 2850 );

--部門10和30中的工資超過1500的僱員名及工資

select deptno,ename,sal from scott.emp a where a.deptno in(10,30) and a.sal>1500 order by sal desc ;

結果:



--在1981年2月1日至1981年5月1日之間僱傭的僱員名,崗位及僱傭日期,並以僱傭日期先後順序排序

select ename as 姓名,job as 崗位,hiredate as 僱傭日期 from scott.emp a where a.hiredate between to_date('1981-02-01','yyyy-mm-dd') and to_date('1981-05-01','yyyy-mm-dd') order by a.hiredate asc ;

結果:



select * from scott.emp where hiredate >to_date('1981-02-01','yyyy-MM-dd');

--查詢獲得補助的所有僱傭名,工資及補助額,並以工資和補助的降序排序

select ename,sal,comm from scott.emp a where a.comm > all(0) order by comm desc;

--工資低於1500的員工增加10%的工資,工資在1500及以上的增加5%的工資並按工資高低排序(降序)

select ename as 員工姓名,sal as 補發前的工資,case when sal<1500 then (sal+sal*0.1) else (sal+sal*0.05) end 補助後的工資 from scott.emp order by sal desc ;

結果:



--查詢公司每天,每月,每季度,每年的資金支出數額

select sum(sal/30) as 每天發的工資,sum(sal) as 每月發的工資,sum(sal)*3 as 每季度發的工資,sum(sal)*12 as 每年發的工資 from scott.emp;

結果:



--查詢所有員工的平均工資,總計工資,最高工資和最低工資

select avg(sal) as 平均工資,sum(sal) as 總計工資,max(sal) as 最高工資,min(sal) as 最低工資 from scott.emp;

結果:



--每種崗位的僱員總數和平均工資

select job as 崗位,count(job) as 崗位僱員總數,avg(sal) as 平均工資 from scott.emp group by job order by 平均工資 desc;

結果:



--僱員總數以及獲得補助的僱員數

select count(*) as 公司僱員總數,count(comm) as 獲得補助的僱員人數 from scott.emp ;

--管理者的總人數

--僱員工資的最大差額

select max(sal),min(sal),(max(sal) - min(sal)) as 員工工資最大差額 from scott.emp ;

--每個部門的平均工資

select deptno,avg(sal) from scott.emp a group by a.deptno;

結果:



--查詢每個崗位人數超過2人的所有職員資訊

select * from scott.emp a,(select c.job,count(c.job) as sl from scott.emp c group by c.job ) b where b.sl>2 and a.job=b.job;

結果:



select * from scott.emp a where a.empno in(select mgr from scott.emp ) and (select count(mgr) from scott.emp)>2 ;

結果:



--處理重複行資料資訊(刪除,查詢,修改)

select * from a1 a where not exists (select b.rd from (select rowid rd,row_number() over(partition by LOAN, BRANCH order by BEGIN_DATE desc) rn from a1) b where b.rn = 1 and a.rowid = b.rd);

--查詢emp表資料資訊重複問題

select * from scott.emp a where exists(select b.rd from(select rowid rd,row_number() over(partition by ename,job,mgr,hiredate,sal,comm,deptno order by empno asc) rn from scott.emp) b where b.rn=1 and a.rowid=b.rd);

--initcap:返回字串,字串第一個字母大寫

select initcap(ename) Upp from scott.emp ;

結果:



--ascii:返回與指定的字元對應的十進位制數

select ascii(a.empno) as 編號,ascii(a.ename) as 姓名,ascii(a.job) as 崗位 from scott.emp a ;

結果:



--chr:給出整數,返回對應的字元

select chr(ascii(ename)) as 姓名 from scott.emp ;

結果:



--concat:連線字串

select concat(a.ename,a.job)|| a.empno as 字元連線 from scott.emp a;

結果:



--instr:在一個字串中搜索指定的字元,返回發現指定的字元的位置

select instr(a.empno,a.mgr,1,1) from scott.emp a ;

--length:返回字串的長度

select ename,length(a.ename) as 長度,a.job,length(a.job) as 長度 from scott.emp a ;

--lower:返回字串,並將所返回的字元小寫

select a.ename as 大寫,lower(a.ename) as 小寫 from scott.emp a ;

結果:



--upper:返回字串,並將返回字串都大寫

select lower(a.ename) as 小寫名字,upper(a.ename) as 大寫名字 from scott.emp a ;

結果:



--rpad:在列的右邊貼上字元,lpad: 在列的左邊貼上字元(不夠字元則用*來填滿)

select lpad(rpad(a.ename,10,'*'),16,'*') as 貼上 from scott.emp a ;

結果:



--like不同角度的使用

select * from scott.emp where ename like '%XXR%';

select * from scott.emp where ename like '%S';

select * from scott.emp where ename like 'J%';

select * from scott.emp where ename like 'S';

select * from scott.emp where ename like '%S_';

--每個部門的工資總和

select a.ename,sum(sal) from scott.emp a group by ename;

--每個部門的平均工資

select a.deptno,avg(sal) from scott.emp a group by deptno ;

--每個部門的最大工資

select a.deptno,max(sal) from scott.emp a group by deptno ;

--每個部門的最小工資

select a.deptno,min(sal) from scott.emp a group by deptno ;

--查詢原工資佔部門工資的比率

select deptno ,sal,ratio_to_report(sal) over(partition by deptno) sal_ratio from scott.emp ;

--查詢成績不及格的所有學生資訊(提示:沒有對應的表,只是意思意思。不及格人數大於等於三才能查)

select * from scott.emp where empno in(select distinct empno from scott.emp where 3<(select count(sal) from scott.emp where sal<3000) and empno in(select empno from scott.emp where sal<3000));

結果:



--查詢每個部門的平均工資

select distinct deptno,avg(sal) from scott.emp group by deptno  order by deptno desc;

--union組合查出的結果,但要求查出來的資料型別必須相同

select sal from scott.emp where sal >=all(select sal from scott.emp ) union select sal from scott.emp ;

select * from scott.emp a where a.empno between 7227 and 7369 ;--只能從小到大

---------建立表空間  要用擁有create tablespace許可權的使用者,比如sys

create tablespace tbs_dat datafile 'c:\oradata\tbs_dat.dbf' size 2000M;

---------新增資料檔案

alter tablespace tbs_dat add datafile 'c:\oradata\tbs_dat2.dbf' size 100M;

---------改變資料檔案大小

alter database datafile 'c:\oradata\tbs_dat.dbf' resize 250M;

---------資料檔案自動擴充套件大小

alter database datafile 'c:\oradata\tbs_dat.dbf' autoextend on next 1m maxsize 20m;

---------修改表空間名稱

alter tablespace tbs_dat rename to tbs_dat1;

---------刪除表空間  and datafiles 表示同時刪除物理檔案

drop tablespace tbs_dat including contents and datafiles;

--substr(s1,s2,s3):擷取s1字串,從s2開始,結束s3

select substr(job,3,length(job)) from scott.emp ;

--replace:替換字串

select replace(ename,'LL','aa') from scott.emp;

select * from scott.test;

insert into scott.test(ename,job) values('weather','好');

insert into scott.test(ename,job) values('wether','差');

--soundex:返回一個與給定的字串讀音相同的字串

select ename from scott.test where soundex(ename)=soundex('wether');

--floor:取整數

select sal,floor(sal) as 整數 from scott.emp ;

--log(n,s):返回一個以n為低,s的對數

select empno,log(empno,2) as 對數 from scott.emp ;

--mod(n1,n2):返回一個n1除以n2的餘數

select empno,mod(empno,2) as 餘數 from scott.emp ;

結果:



--power(n1,n2):返回n1的n2次方根

select empno,power(empno,2) as 方根 from scott.emp ;

--round和trunc:按照指定的精度進行舍入

select round(41.5),round(-41.8),trunc(41.6),trunc(-41.9) from scott.emp ;

--sign:取數字n的符號,大於0返回1,小於0返回-1,等於0返回0

select sign(45),sign(-21),sign(0) from scott.emp ;

 子查詢

1.單行子查詢
select * from emp
where sal > (select sal from emp where empno > 7876);
 
2.子查詢空值/多值問題
如果子查詢未返回任何行,則主查詢也不會返回任何結果。
(空值)select * from emp where sal >(select sal from emp where empno=6666);
 
如果子查詢返回單行結果,則為單行子查詢,可以在主查詢中對其使用相應的單行記錄比較運算子
(正常)select * from emp
where sal > (select sal from emp where empno > 7876);
 
如果子查詢返回多行結果,則為多行子查詢,此時不允許對其使用單行記錄比較運算子
(多值)select * from emp where sal > (select avg(sal) from emp group by deptno);--非法
 
3.多行子查詢
select * from emp where sal > any(select avg(sal) from emp group by deptno);
注:any(collection) 函式.  只要大於collection中任意一個即滿足>條件。與in用法類似
select * from emp where sal > all(select avg(sal) from emp group by deptno);
注:all(collection)函式,比子查詢返回結果中的所有值都大才滿足>條件。
select * from emp where job in (select job from emp where ename = 'Smith' or ename = 'Halen');
 
4.TopN查詢
select * from emp where rownum = 1 or rownum = 2;
排序,列出所有記錄或前N條記錄
select * from (select * from emp order by sal desc) 
where rownum <= 5;--rownum只能是小於等於”<=”n.
 
排序,列出指定區間的記錄(下面的查詢語句執行後不會有任何結果。)
select 欄位列表
from   (select 欄位列表 from 表名 order by 排序欄位)
where rownum>=11 and rownum<=15;
 
如果想實現大於等於,或者between,則如下程式碼:
select 欄位列表 from
(select rownum num, 欄位列表 from 表名 order by 排序欄位)
where num >= 8 and num <=16;
 
原因分析:rownum是查詢過後才按順序排的,假如你的條件是rownum>1;那麼返回資料的第一條(rownum是1)就不符合要求了,
然後第二條資料變成了現在的第一條,結果這一條rownum又變成1了又不符合要求了,以此類推 就沒有返回結果。
 
5.分頁查詢
通過第4點對rownum的理解之後,就可以寫出我們想要的分頁語句了。
仍然不清楚的,可以先去了解一下Oracle偽列rownum,rowid
select 欄位列表
from (select rownum no,t.* from table_name t)
where no > 2 and no < 5;
---------------------------------------------
1、查詢部分分為主查詢和子查詢; 
2、根據返回值的記錄多少分為單行子查詢和多行子查詢;單行子查詢用單行比較符=連線;多行子查詢用多行比較符in連線; 
3、子查詢的內容可以放在FROM後面,也可以放在WHERE後面,也可以放在HAVING後面; 
4、完整的SELECT語句可以擁有GROUP BY,HAVING子句,也可以使用組函式;也可以從多個表中查詢; 
5、子查詢的內容必須用小括號來界定; 
6、例子1:子查詢(子句)在FROM後面的:

SELECT first_name,last_name
FROM 
(SELECT first_name,last_name
FROM s_emp
WHERE 1=1
AND first_name='國藩'
)
WHERE 1=1
AND last_name='曾';
1
2
3
4
5
6
7
8
9
精簡一下就是:

SELECT first_name,last_name
FROM 
(子查詢)
WHERE 1=1
AND last_name='曾';
1
2
3
4
5
這裡就像是一個定於從句,這裡的(子查詢)就替換成了另一個select語句;這裡要注意,子查詢語句裡沒有表示結束的分號;並且主查詢的範圍必須小於子查詢,否則會因查不到資料而報錯;

7、例子2:子查詢(子句)在WHERE後面的

SELECT first_name,last_name 
FROM s_emp
WHERE dept_id=
(
SELECT dept_id
FROM s_emp
WHERE last_name='曾'
);
1
2
3
4
5
6
7
8
這裡查詢的是姓是和‘曾’的所在的部門ID相同(只有一個姓曾)的所有人的姓名;

這裡,有人問了,如果有好幾個姓曾的人怎麼辦,我要把所有姓曾人所在部門的人的姓名都查出來怎麼辦,這裡就是多行子查詢;把等號換成in即可;
---------------------