一、基本查詢 對於ORACLE,最常關註的無非就是關於ORACLE的查詢之類的語句了,而在PL/SQL上面,筆者使用的一般有兩種不同的查詢視窗:CommandWindow和SQLWindow兩種不同的視窗。 1.1現在將一些需要在CommandWindow使用的命令羅列如下: 上述分別是查詢當前用戶 ...
一、基本查詢
對於ORACLE,最常關註的無非就是關於ORACLE的查詢之類的語句了,而在PL/SQL上面,筆者使用的一般有兩種不同的查詢視窗:CommandWindow和SQLWindow兩種不同的視窗。
1.1現在將一些需要在CommandWindow使用的命令羅列如下:
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 Connected as scott@ORCL SQL> show user; User is "scott" SQL> desc emp; Name Type Nullable Default Comments -------- ------------ -------- ------- -------- EMPNO NUMBER(4) ENAME VARCHAR2(10) Y JOB VARCHAR2(9) Y MGR NUMBER(4) Y HIREDATE DATE Y SAL NUMBER(7,2) Y COMM NUMBER(7,2) Y DEPTNO NUMBER(2) Y
上述分別是查詢當前用戶的命令,以及查詢表結構的命令;
1.2基本查詢
下麵介紹的是一些簡單的查詢:
/*查詢該用戶下麵的所有的表*/ select * from tab; /*查詢所有數據*/ select * from emp; /*通過特點的列名查詢數據*/ select empno,ename,job from emp; /*給列名命名別名來查詢數據*/ select empno 員工號, ename 員工名, job 職位, MGR 上司, hiredate 入職時間, sal 工資, comm 獎金, deptno 部門號 from emp; /*查詢員工信息:員工號 姓名 月薪 年薪 獎金 年收入*/ select empno,ename,sal,sal*12,comm from emp; /*如果不知道某一個表的列有哪些,可以給表一個簡單別名,進行查詢*/ select a.empno,a.ename,a.sal,a.sal*12,a.comm from emp a;
1.3NVL函數
如果,我們要查詢的是某一個員工的年薪的話,那麼年薪=月薪*12+獎金,雖然ORACLE進行的查詢語句可以進行簡單加減,但是會出現不符合我們要求的結果:
/*不使用NVL函數*/ select empno 員工號, ename 姓名, sal 薪水, sal * 12 年薪, comm 獎金, sal * 12 + comm 總年薪 from emp;
結果:
我們會發現,當沒有獎金的時候,查詢出來的總年薪為空,這說明瞭SQL語句中如果有表達式為null,那麼結果為空。所以我們就會使用NVL()函數來改善結果。如下所示:
/*使用NVL函數*/ select empno 員工號, ename 姓名, sal 薪水, sal * 12 年薪, comm 獎金, sal * 12 + NVL(comm, 0) 總年薪 from emp;
這時候結果為:
解釋一下NVL()函數:
1.NVL(a,b)如果a是NULL,用b替代,如果a是非NULL,就不用b替代,直接返回a的值,NVL()作用於任何類型,即(number/varchar2/date)
2.使用NVL2(a,b,c)通用函數,如果a不為NULL,取b值,否則取c值
1.4使用別名進行查詢註意點
使用列別名,查詢員工的編號,姓名,月薪,年薪,年收入(年薪+獎金),AS大小寫都可且可以省略AS,別名用雙引號:
select empno AS "編號",ename as "姓名",sal "月薪" from emp; 或者 select empno AS 編號,ename as 姓名,sal 月薪 from emp; 或者 select empno AS "編號",ename as 姓名,sal "月 薪" from emp;
不加雙引號的別名不能有空格;加了雙引號的別名可以有空格
要加只能加雙引號,不能加單引號,因為在oracle中單引號表示字元串類型或者是日期類型
1.5Oracle中啞表(偽表)的使用
/*使用dual啞表或者偽表,使用字元串連接符號||,輸出"hello world",在oracle中from是必須寫的*/ select 'hello'||'world' 結果 from dual; /*使用啞表查詢當前系統時間*/ select sysdate from dual;
1.6字元連接符號的使用
/*使用字元串連接符號||,顯示如下格式信息:****的薪水是****美元*/ select ename || '的薪水是' || sal || '美元' from emp;
1.7帶where條件和between...and...過濾的查詢
/*查詢emp表中20號部門的員工信息*/ select * from emp where deptno = 20; /*查詢姓名是SMITH的員工,字元串使用'',內容大小寫敏感*/ select * from emp where ename = 'SMITH'; /*查詢1980年12月17日入職的員工,註意oracle預設日期格式(DD-MON-RR表示2位的年份)*/ select * from emp where hiredate = '17-12月-80'; /*查詢工資大於1500的員工*/ select * from emp where sal > 1500; /*查詢工資不等於1500的員工【!=或<>】*/ select * from emp where sal <> 1500; /*查詢薪水在1300到1600之間的員工,包括1300和1600*/ select * from emp where (sal>=1300) and (sal<=1600); 或 select * from emp where sal between 1300 and 1600; /*查詢薪水不在1300到1600之間的員工,不包括1300和1600*/ select * from emp where sal NOT between 1300 and 1600; /*查詢入職時間在"1981-2月-20"到"1982-1月-23"之間的員工*/ select * from emp where hiredate between '20-2月-81' and '23-1月-82'; 註意: 1)對於數值型,小數值在前,大數值在後 2)對於日期型,年長值在前,年小值在後 /*查詢20號或30號部門的員工,例如:根據ID號,選中的員工,批量刪除*/ select * from emp where (deptno=20) or (deptno=30); 或 select * from emp where deptno in (30,20); /*查詢不是20號或30號部門的員工*/ select * from emp where deptno NOT in (30,20); /*查詢姓名以大寫字母S開頭的員工,使用%表示0個,1個或多個字元*/ select * from emp where ename like 'S'; 等價於 select * from emp where ename = 'S'; select * from emp where ename like 'S%'; 註意: 凡是精確查詢用=符號 凡是不精確查詢用like符號,我們通常叫模糊查詢 /*查詢姓名以大寫字母N結束的員工*/ select * from emp where ename like '%N'; /*查詢姓名第一個字母是T,最後一個字母是R的員工*/ select * from emp where ename like 'T%R'; /*查詢姓名是4個字元的員工,且第二個字元是I,使用_只能表示1個字元,不能表示0個或多個字元*/ select * from emp where ename like '_I__'; /*插入一條姓名為'T_IM'的員工,薪水1200*/ insert into emp(empno,ename) values(1111,'T_IM'); /*查詢員工姓名中含有'_'的員工,使用\轉義符,讓其後的字元回歸本來意思【like '%\_%' escape '\'】*/ select * from emp where ename like '%\_%' escape '\'; /*插入一個姓名叫'的員工*/ insert into emp(empno,ename) values(2222,''''); /*插入一個姓名叫''的員工*/ insert into emp(empno,ename) values(2722,''''''); /*查詢所有員工信息,使用%或%%*/ select * from emp; select * from emp where ename like '%'; select * from emp where ename like '%_%'; /*查詢獎金為null的員工*/ select * from emp where comm is null; 註意:null不能參數=運算 null能參數number/date/varchar2類型運算 /*查詢獎金為非null的員工*/ select * from emp where comm is not null; /*查詢無佣金且工資大於1500的員工*/ select * from emp where (comm is null) and (sal > 1500); /*查詢工資是1500或3000或5000的員工*/ select * from emp where sal in (4000, 10000, 1500, 3, 300, 3000, 5000); /*查詢職位是"MANAGER"或職位不是"ANALYST"的員工(方式一,使用!=或<>)*/ select * from emp where (job = 'MANAGER') or (job <> 'ANALYST'); /*查詢職位是"MANAGER"或職位不是"ANALYST"的員工(方式二,使用not)*/ select * from emp where (job='MANAGER') or (not(job='ANALYST'));
1.8使用order by進行排序
/*查詢員工信息(編號,姓名,月薪,年薪),按月薪升序排序,預設升序,如果月薪相同,按oracle內置的校驗規則排序*/ select empno, ename, sal, sal * 12 from emp order by sal asc; /*查詢員工信息(編號,姓名,月薪,年薪),按月薪降序排序*/ select empno, ename, sal, sal * 12 from emp order by sal desc; /*查詢員工信息,按入職日期降序排序,使用列名*/ select empno, ename, sal, hiredate, sal * 12 "年薪" from emp order by hiredate desc; /*order by後面可以跟列名、別名、表達式、列號(從1開始,在select子句中的列號)*/ 列名: select empno, ename, sal, hiredate, sal * 12 "年薪" from emp order by hiredate desc; 別名: select empno, ename, sal, hiredate, sal * 12 "年薪" from emp order by "年薪" desc; 表達式: select empno, ename, sal, hiredate, sal * 12 "年薪" from emp order by sal * 12 desc; 列號,從1開始: select empno, ename, sal, hiredate, sal * 12 "年薪" from emp order by 5 desc; /*查詢員工信息,按佣金升序或降序排列,null值看成最大值*/ select * from emp order by comm desc; /*查詢員工信息,對有佣金的員工,按佣金降序排列,當order by 和 where 同時出現時,order by 在最後*/ select * from emp where comm is not null order by comm desc; /*查詢員工信息,按工資降序排列,相同工資的員工再按入職時間降序排列*/ select * from emp order by sal desc, hiredate desc; select * from emp order by sal desc, hiredate asc; 註意:只有當sal相同的情況下,hiredate排序才有作用 /*查詢20號部門,且工資大於1500,按入職時間降序排列*/ select * from emp where (deptno = 20) and (sal > 1500) order by hiredate desc; select * from emp where deptno in (10, 20, 30, 50, 'a');
1.9單行函數
單行函數:只有一個參數輸入,只有一個結果輸出
多行函數或分組函數:可有多個參數輸入,只有一個結果輸出
/*測試lower/upper/initcap函數,使用dual啞表*/ select lower('www.BAIdu.COM') from dual;//全部小寫 select upper('www.BAIdu.COM') from dual;//全部大寫 select initcap('www.BAIdu.COM') from dual;//首字母大寫,其餘小寫 /*測試concat/substr函數,從1開始,表示字元,不論中英文*/ select concat('hello','你好') from dual;//正確 select concat('hello','你好','世界') from dual;//錯誤,說明瞭參數只能有兩個 select 'hello' || '你好' || '世界' from dual;//正確 select concat('hello',concat('你好','世界')) from dual;//正確 註意:concat表示將字元連接起來 select substr('hello你好',5,3) from dual; 5表示從第幾個字元開始算,第一個字元為1,中英文統一處理 3表示連續取幾個字元 /*測試length/lengthb函數,編碼方式為UTF8/GBK,一個中文占3/2個位元組長度,一個英文一個位元組*/ select length('hello你好') from dual; select lengthb('hello你好') from dual; /*測試instr/lpad/rpad函數,從左向右找第一次出現的位置,從1開始*/ select instr('helloworld','o') from dual; 註意:找不到返回0 大小寫敏感 select LPAD('hello',10,'#') from dual;//結果:#####hello select RPAD('hello',10,'#') from dual;//結果:hello##### /*測試trim/replace函數*/ select trim(' ' from ' he ll ') from dual; select replace('hello','l','L') from dual; /*測試round/trunc/mod函數作用於數值型*/ select round(3.1415,3) from dual;//3.142 select trunc(3.1415,3) from dual;//3.141 select mod(10,3) from dual;//1 當前日期:sysdate = 01-10月-17 /*測試round作用於日期型(month)*/ select round(sysdate,'month') from dual;//2017-10-01 /*測試round作用於日期型(year)*/ select round(sysdate,'year') from dual;//2018-01-01 /*測試trunc作用於日期型(month)*/ select trunc(sysdate,'month') from dual;//2017-10-01 /*測試trunc作用於日期型(year)*/ select trunc(sysdate,'year') from dual;//2017-01-01 /*顯示昨天,今天,明天的日期,日期類型 +- 數值 = 日期類型*/ select sysdate-1 "昨天",sysdate "今天",sysdate+1 "明天" from dual; /*以年和月形式顯示員工近似工齡,日期-日期=數值,假設:一年以365天計算,一月以30天計算*/ select ename "姓名",round(sysdate-hiredate,0)/365 "天數" from emp; /*使用months_between函數,精確計算到年底還有多少個月*/ select months_between('31-12月-15',sysdate) from dual; /*使用months_between函數,以精確月形式顯示員工工齡*/ select ename "姓名",months_between(sysdate,hiredate) "精確月工齡" from emp; /*測試add_months函數,下個月今天是多少號*/ select add_months(sysdate,1) from dual; /*測試add_months函數,上個月今天是多少號*/ select add_months(sysdate,-1) from dual; /*測試next_day函數,從今天開始算,下一個星期三是多少號【中文平臺】*/ select next_day(sysdate,'星期三') from dual; /*測試next_day函數,從今天開始算,下下一個星期三是多少號【中文平臺】*/ select next_day(next_day(sysdate,'星期三'),'星期三') from dual; /*測試next_day函數,從今天開始算,下一個星期三的下一個星期日是多少號【中文平臺】*/ select next_day(next_day(sysdate,'星期三'),'星期日') from dual; /*測試last_day函數,本月最後一天是多少號*/ select last_day(sysdate) from dual; /*測試last_day函數,本月倒數第二天是多少號*/ select last_day(sysdate)-1 from dual; /*測試last_day函數,下一個月最後一天是多少號*/ select last_day(add_months(sysdate,1)) from dual; /*測試last_day函數,上一個月最後一天是多少號*/ select last_day(add_months(sysdate,-1)) from dual; 註意: 1)日期-日期=天數 2)日期+-天數=日期
1.10oracle中的三大類型的轉換
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月
/*查詢1980年12月17日入職的員工(方式一:日期隱示式轉換)*/ select * from emp where hiredate = '17-12月-80'; /*使用to_char(日期,'格"常量"式')函數將日期轉成字元串,顯示如下格式:2015 年 04 月 25 日 星期六*/ select to_char(sysdate,'yyyy" 年 "mm" 月 "dd" 日 "day') from dual; /*使用to_char(日期,'格式')函數將日期轉成字元串,顯示如格式:2015-04-25今天是星期六 15:15:15*/ select to_char(sysdate,'yyyy-mm-dd"今天是"day hh24:mi:ss') from dual; 或 select to_char(sysdate,'yyyy-mm-dd"今天是"day HH12:MI:SS AM') from dual; /*使用to_char(數值,'格式')函數將數值轉成字元串,顯示如下格式:$1,234*/ select to_char(1234,'$9,999') from dual; /*使用to_char(數值,'格式')函數將數值轉成字元串,顯示如下格式:¥1,234select to_char(1234,'$9,999') from dual;*/ select to_char(1234,'L9,999') from dual; /*使用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'); /*使用to_number('字元串')函數將字元串‘123’轉成數字123*/ select to_number('123') from dual; 註意: select '123' + 123 from dual;//246 select '123' || 123 from dual;//123123
1.11通用函數
使用NVL(a,b)通用函數,統計員工年收入,NVL()作用於任何類型,即(number/varchar2/date)
通用函數:參數類型可以是number或varchar2或date類型
使用NVL2(a,b,c)通用函數,如果a不為NULL,取b值,否則取c值,統計員工年收入
使用NULLIF(a,b)通用函數,在類型一致的情況下,如果a與b相同,返回NULL,否則返回a,比較10和10.0是否相同
使用SQL99標準通用語法中的case表達式,將職位是分析員的,工資+1000;職位是經理的,工資+800;職位是其它的,工資+400
case 欄位
when 條件 then 表達式1
when 條件 then 表達式2
else 表達式n
end
使用oracle專用語法中的decode()函數,職位是分析員的,工資+1000;職位是經理的,工資+800;職位是其它的,工資+400
decode(欄位,條件1,表達式1,條件2,表達式2,...表達式n)
單引號出現的地方如下:
1)字元串,例如:'hello'
2)日期型,例如:'17-12月-80'
3)to_char/to_date(日期,'YYYY-MM-DD HH24:MI:SS')
雙引號出現的地方如下:
1)列別名,例如:select ename "姓 名" from emp
2)to_char/to_date(日期,'YYYY"年"MM"月"DD"日" HH24:MI:SS')