1. 程式人生 > >Oracle基本語法查詢語句

Oracle基本語法查詢語句

Oracle基本查詢語法 本文含含: 基礎/基本查詢/排序/函式(單/多)

一.前言知識

1.oracle如何操作硬碟上的檔案,最終都是以程序方式操作硬碟上的檔案,最基本程序:讀 寫 ,還有其他客戶端訪問記憶體中的資料庫例項,例項在記憶體中有很多塊,小方塊取決於客戶端的個數,大方塊叫做SGA:system global area 系統全域性區域,一個記憶體例項只有一個, 小方塊叫PGA:process global area 程序全域性區域,(見圖) 在寫資料時,客戶端操作的PGA先寫到SGA,SGA再統一寫到硬碟(分兩階段提交),可以減少訪問資料庫的次數,提高寫入速度 2.oracle的事務提交之後,
資料不一定會儲存下來,臨時表的資料是會被刪除的
//回滾使用rollback; ,需要事務, Oracle開啟事務是自動預設開啟的,我們的操作本身就在事務中, Oracle資料庫事務預設是不自動提交. oracle中事務提交後,也可以撤銷,通過閃回方式(flashback) , mysql開啟事務是手動開啟, start transaction ,commit提交 MYSQL資料庫事務預設是自動提交的.

二.語句基礎知識

1.學前基礎知識: 1.字串大小寫,日期格式,都有嚴格格式要求. 2.檢視設定: select * from v$nls_parameters; //檢視當前設定:字符集,日期格式 ........
修改: alter session/system set NLS_CALENDAR='yyyy-mm-dd'; //設定日期格式 Oracle顯示會自動分頁, 設定分頁大小: set pagesize 20; 連線oracle:sqlplus scott/[email protected]/orcl 所有表: select * from tab;//列出當前使用者下的表和檢視
spool d:\基本查詢.txt //錄屏語句,會把命令窗體的內容給記錄下來 show user; //查詢當前使用者 desc emp //查看錶的結構 / //表示執行上一條語句 host cls //Windows清屏 host clear //linux清屏
lsnrctl statusstart /stop; //oracle的監聽器狀態 檢視,啟動或關閉 netca視覺化監聽配置 show linesize; //檢視當前顯示的行寬 set linesize 150; //設定行寬 clo(colum縮寫) ename for(format) a8 // 設定列寬, 此處設定名字(字元)這個列寬度為8, for表示格式 col sal for 9999; //設定數字的寬度 ,一個9代表一個數字, set time on //可以讓sql語句前顯示時間,如下: 11:23:21 SQL> set time off set timing on //可以開啟時間記錄,記錄程式執行時間
2.字串 : 字串可以是select 列表中的一個字元,數字,日期; 日期和字元只能在單引號中出現, 雙引號用於列的別名; 3.區分sql語句 還是sqlplus語句 sqlplus是oracle提供的命令列工具.在此工具中可以執行sql語句, sql語句的關鍵詞不能使用縮寫,如select.insert,Update,delete都是sql語句, sqlplus語句的關鍵詞可以縮寫,如 ed, c , for col ,desc, isqlplus是sqlplus的網頁版 4.修改錯誤語句:c代表change命令
select *   froo emp ; //from輸入錯誤, 修改錯誤字元如下: 第2行出錯了, 輸入:2 //回車;定位到第二行 輸入: c/froo/from 回車, c /修改誰/改成誰 輸入 / 執行上一條語句即可
5..亂碼處理: 1.檢視伺服器端編碼 select userenv('language') from dual; 我實際查到的結果為:AMERICAN_AMERICA.ZHS16GBK 2.執行語句 select * from V$NLS_PARAMETERS 檢視第一行中PARAMETER項中為NLS_LANGUAGE 對應的VALUE項中是否和第一步得到的值一樣。 如果不是,需要設定環境變數.否則PLSQL客戶端使用的編碼和伺服器端編碼不一 致,插入中文時就會出現亂碼. 3.設定環境變數 計算機->屬性->高階系統設定->環境變數->新建 設定變數名:NLS_LANG,變數值:第1步查到的值, 我的是        SIMPLIFIED CHINESE_CHINA.ZHS16GBK 6.修改oracle密碼 1.管理員登入 : sqlplus system/system as sysdba; 2.解鎖: alter user scott account unlock/lock ; 3.改密碼: alter user scott identified by 新密碼; 7.使用者查詢
select * from dba_users; 檢視資料庫裡面所有使用者,前提你是有dba許可權帳號,如sys,system select * from all_users;  檢視你能管理的所有使用者! select * from user_users; 檢視當前使用者資訊 !

三.查詢語句

1.,基本查詢
select * from emp; //查詢所有, * 表示所有 select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp; //通過列名查詢指定列 select ename,job,sal from emp; //算數計算 select empno, ename, sal,sal*12 from emp;//查詢工號,姓名,月薪,年薪
2..空值問題 :空值是無效的,未指定的,未知的或不可預知的值,不是空格或者0; 1.null永遠 != null 2.包含null的表示式都為null; 因此判斷一個值是否為空,不能用 = 或 != ; enameis null; 或 ename is not null; 3.如果集合中有空值,不能使用not in(set), 但可以使用 in(set) 4. oracle中,空值最大,因此降序排序空值在最前,升序則在最後, 降序使用 nulls last,會讓null值排後面, 升序使用 nulls first ,會讓空值排前面. 5.組函式(多行函式)自動濾空;可用濾空函式來遮蔽他的濾空功能 3..慮空函式: nvl(a,b) //即當a的值為空時,返回b, a不為空返回a本身,
nvl2 //錯誤查詢 獎金為空的人沒有年收入: 查詢員工,姓名,月薪,年薪,獎金,年收入 //select empno,ename,sal,sal*12,comm, sal*12+comm from emp; //因為含null的表示式都為null select empno,ename,sal,sal*12,comm, sal*12+nvl(comm,0) from emp; //正確查詢,使用慮空函式
4..起別名:
select empno as "員工號", ename "姓名" ,sal 月薪 ,sal*12,comm,sal*12+nvl(comm,0) from emp; //as 用於起別名,可以省略! //普通別名可以不加雙引號, 若別名中有 空格/關鍵字/特殊字元/數字, 需要加"",
5.去重複記錄:select distinct deptno from emp; select distinctdeptno ,job from emp; //distinct 作用於後面所有列,這些列組合起來是不一樣的,那就算是不重複的, 6.連線符: || concat函式 //連線字串 select concat('Hello',' world'); //這是錯的 // 由於oracle遵循sql99標準,沒有from 不行,但from後面是表,如果操作的資料跟表沒有關係,就使用 from dual; 做佔位符. dual表,僅僅是為了滿足oracle的語法要求,是偽表,佔位用的, 同樣有偽列; 如: select concat('Hello',' world') from dual;//這是對的. select 3+2 from dual; 查詢員工薪水: select ename||'的薪水是'||sal 資訊 from emp; //連線字串,日期和數字只能用單引號, 7.where 語句若有多條件時,解析的順序是從右往左. 因此,對於and條件,應該把為假的條件放右邊,這樣就不判斷左邊的了,,短路,提高效率 對於 or 儘可能把為真的條件放右邊,

四.條件過濾

1.where條件篩選 select * from emp where ename='KING'; //字串區分大小寫 select * from emp where hiredate='17-11月-81'; //預設格式: DD-MM月-YY;(設定格式見上面) 2.比較運算: =, >, >=, <, <= , <>或!= 賦值使用 := 符號 如 : a number := 0 ; //變數名在前,變數型別 := 變數值 between.... and ... 在兩個值之間,含邊界, 必須小值在前,大值在後, 日期也是一樣小值在前. in(set) 等於值列表中的一個 like 模糊查詢 is null ,判斷空值 //查詢薪水 在1000~2000之間 select * from emp where sal>1000 and sal<2000; select * from emp where sal between 1000and 2000; //查詢10號20號部門的員工,或查詢此2部門之外的員工 select * from emp where deptno not in(10,20); 注: 3.如果集合中有空值,不能使用not in(set), 但可以使用 in(set) select * from emp where deptno not in(10,20,null); //錯誤語句, //模糊查詢 % :表示任意個字元 _:表示一個字元 select * from emp where ename like 'S%'; //查詢姓名s開頭的員工; select * from emp where ename like '____'; //查詢姓名4個字的員工 //查詢姓名含有"_"下劃線的 使用 escape 宣告 轉義字元 ,習慣用 \ , select * from emp where ename like '%\_%'escape '\'; 3.邏輯運算子 注:where 語句若有多條件時,解析的順序是從右往左. and 邏輯並or 邏輯或not 邏輯否 如: where condition1 and condition2 where condition2 and condition1 是兩條不一樣的語句 ,但結果一樣, 3.排序order by 此句在select語句結尾 1.ASC 預設升序(ascend) DESC(descend)降序 order by 後面可以跟 : 列名, 表示式 , 別名 , 序號 select empno ,ename ,sal,sal*12 from emp order by sal*12 desc; //表示式做排序條件 select empno ,ename ,sal,sal*12 年薪 from emp order by 年薪 desc; //別名 select empno ,ename ,sal, sal*12 from emporder by 4 desc; //按序號, 序號須在有效範圍內 2.. 多個列排序 order by 作用於所有列先按左邊(最近) 排, 相同了,再按右邊排 //降序只作用於最近列 select empno ,ename,sal,deptno from emp order by deptno,sal; //預設升序 select empno ,ename,sal,deptno from emp order by deptno,sal desc;//降序只作用於最近列 select empno ,ename,sal,deptno from emp order by deptno desc, sal asc; 排序的時候,列中如果有空值,採用降序,空值會排在前面, 原因:oracle中空值最大 解決: null last 或null last select * from emp order by comm desc nulls last;

五.函式

單行函式:只對一行進行變換得到一個結果,如nvl(), concat() 多行函式:對多行操作產生結果,如:max()等 1.單行函式: 字元,數值,日期,轉換,通用,條件表示式 1.字元函式 -單行 1.大小寫控制函式:lower , upper , initcap(首字母大寫) select lower('Hello world') 轉小寫,upper('Hello world') 轉大寫,initcap('hello') 首字母大寫 from dual; 2. 字元控制函式 concat(a,b) 連線拼接a,b兩個字串 substr 求一個串的子串 substr(a,b) 從a中第b位取到最後 substr(a,b,c) 從a中 第b位 取c個 length(s) / lengthb(s) 長度:字元數 /位元組數 instr(a,b) 在一個串中查詢子串 instr(a,b) 在a中查詢b,返回下標; lpad(a,b,c) | rpad(a,b,c) 左填充 右填充 對a填充, 填充b位, 用c填充 trim 去掉前後指定字元 replace(a,b,c) 替換a中的b,用c替換 舉例: select instr('helloworld','ll') from dual; //查詢子串 select substr('helloworld',3,3) from dual; //擷取子串 select length('被in個') 字元,lengthb('北京') 位元組 from dual; //長度 select lpad('abc',10,'*') 左, rpad('asd',10,'*') 右 from dual; //左右填充 select trim('h' from 'helloh') from dual; //去掉前後指定字元 select replace('hello','l','*') from dual; //替換 2.數值函式-單行 round(a,b) 四捨五入,對a保留b位小數, round(45.926,-1) 為50 , round(45.926,-2) 為0 trunc(a,b) 截斷,保留幾位小數, 對日期也可以截斷 trunc(45.926,0)為45 trunc(45.926,-1) 為40 , trunc(45.926,-2) 為0 3.日期函式-單行 months_between(a,b) 計算兩個日期差的月數 add_months(a,b) 向指定日期a 加上若干月數b next_day(a) 指定日期的下一個星期幾是幾號 last_day(a) 本月最後一天 round(sysdate,'month') 日期四捨五入:按月四捨五入 trunc 日期截斷 select now(); //mysql中查詢當前時間 select sysdate from dual; //查詢當前日期 舉例: select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; //日期和時間 1.日期運算: 只有加減 ,且不允許 日期+日期 select (sysdate-1) 昨天,sysdate 今天,(sysdate+1) 明天 from dual; 2.計算員工的工齡: 天 星期 月 年 select empno,ename,hiredate,(sysdate-hiredate) 天,(sysdate-hiredate)/7 星期,(sysdate-hiredate)/30 月,(sysdate-hiredate)/365 年 from emp; 3.months_between(a,b) 計算兩個日期差的月數 select ename,hiredate,(sysdate-hiredate)/30 ,months_between(sysdate,hiredate) from emp 4.select add_months(sysdate,53) from dual; //53個月後的日期 5. select next_day(sysdate,'星期三') from dual; //下一個星期三是幾號 6.select round(sysdate,'month'), round(sysdate,'year') from dual; 四捨五入 4.轉換函式: -單行 1.隱式 :oracle自動完成資料型別轉換 2.顯式:手動完成,需要指定格式 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss"今天是"day')from dual; //把日期按格式轉換成字串,由於裡面含文字,不是格式一部分,用""括起來 //查詢員工薪水:兩位小數,千位符,本地貨幣程式碼 select to_char(sal,'L9,999.99')from emp; //把數字按格式轉成字串 5.通用函式-單行 1.nvl(a,b) 當a為空時,返回b, 通用於任何型別 2.nvl2(a,b,c) 當a為空返回c , 否則返回b 3.nullif(a,b) 當a=b時,返回null ,否則返回a, 4.coalesce(a1,a2,a3,...) 從左往右,找到第一個不為空的值 舉例:select sal*12 + nvl2(comm,comm,0) from emp; select nullif('abc','abc') 值 from dual; select nullif('abc','abcd') 值 from dual; select comm,sal,coalesce(comm,sal) "第一個不為null的值" from emp; 6.條件表示式-單行 在sql語句中使用if - else 邏輯 兩種方式: case表示式:sql99的語法,類似basic,比較繁瑣 decode函式:oracle自己的語法,類似java,簡單 decode( 表示式, 條件1,值1,條件2,值2,...., default ) from 表; 舉例: 1.select empno,ename,job,sal 漲前, casejobwhen 'PRESIDENT'then sal+1000 when 'MANAGER' then sal+800 else sal+400 end 漲後 from emp; 2. select empno,ename,job,sal 漲前, decode(job,'PRESIDENT',sal+1000, 'MANAGER',sal+800, sal+400) 漲後 from emp; 2. 多行函式 1.組函式: 分組函式作用於一組資料,並對一組資料返回一個結果 avg count max min sum //組函式有自動慮空功能,不計算為空的內容,可以濾空函式來遮蔽他的濾空功能 舉例: count(distinct expr) //返回表示式非空且不重複的記錄數 select sum(sal) from emp; //求工資總額 select count(*) from emp; //總人數 select sum(sal)/count(*) 一,avg(sal) 二 from emp; //平均工資 兩種方式 select sum(comm)/count(*) 一,sum(comm)/count(comm)二,avg(comm) 三 from emp; //三種方式計算獎金, 後兩中方式結果相同 , 因為只有4個人有獎金, 因為有null, 具體問題具體分析 select count(*), count(nvl(comm,0)) from emp; //結果相同了,慮空了 2.分組函式 group by 注:1.group by先按照第一個列分組;再按照第二列分組;以此類推 2.所有沒有包含在組函式中的列,必須寫在group by 後面, 不寫group by則錯 如 : select a,b,c 組函式(X) from 表 group by a,b,c,d; 舉例: //求每個部門的平均工資 select deptno,avg(sal) from empgroup by deptno; //按不同部門的不同職位 計算總工資 select deptno,job,sum(sal) from empgroup by deptno,joborder by 1; 3.having 過濾分組資料 1.where和having的區別:where後面不能使用多行函式 行已經被分組,使用了組函式,滿足having條件的分組被顯示 //按部門分組,求各部門平均工資 select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000; //查詢10號部門的平均工資 select deptno,avg(sal) from emp group by deptno having deptno=10; 4.group by的增強 select deptno,job,sum(sal) from emp group by deptno,job SQL> + SQL> select deptno,sum(sal) from emp group by deptno SQL> + SQL> select sum(sal) from emp SQL> === 上面三條語句的相加就是下面這條語句的結果 SQL> select deptno,job,sum(sal) from emp group by rollup(deptno,job) SQL> 抽象 SQL> group by rollup(a,b) SQL> = SQL> group by a,b SQL> + SQL> group by a SQL> + SQL> 沒有group by SQL> */ SQL> select deptno,job,sum(sal) from emp group by rollup(deptno,job); break on deptno skip 2 //部門之間顯示2個空行 / //執行上一條語句