Oracle總結【SQL細節、多表查詢、分組查詢、分頁】

前言

在以前已經大概瞭解過Mysql數據庫和學過相關的Oracle知識點,可是過久沒用過Oracle了,就基本忘了...印象中就只有基本的SQL語句和相關一些概念....寫下本博文的緣由就是記載着Oracle一些之前沒注意到的知識點...之後或許會有用...面試

實例與數據庫概念

Oracle數據庫服務器由兩部分組成:算法

  • 實例:理解爲對象,看不見的
  • 數據庫:理解爲類,看得見的

咱們在安裝Oracle的時候,已經填寫過本身數據庫的名稱了,通常實例與數據庫的名稱是一致的...sql

這裏寫圖片描述

若是尚未安裝Oracle數據庫的,能夠看一下我其餘的博文....數據庫

那麼咱們自帶的sqlplus黑色窗口與實例,數據庫之間的關係又是什麼的呢???咱們能夠看下圖:服務器

這裏寫圖片描述

Oracle數據庫把表、視圖等都當作是對象:微信

這裏寫圖片描述


Oracle中的null值

Oracle中若是存在字段是null值的話,那麼在sqlplus中它是不會顯示出來的....若是咱們使用null值的數據與其餘數據進行運算...那麼最終得出的結果都是null值oracle

所以,Oracle提供了NVL(表達式1,表達式2)函數供咱們使用,若是表達式1的值爲null值,那麼就取表達式2的值...固然了,若是表達式1不是null,取的就是表達式1的值函數

還有值得注意的是:null值不能參數=號運算,null能參數number/date/varchar2類型運算性能

Oracle提供了 is null關鍵字來代替=號運算的問題spa

Oracle中的別名

咱們知道在Mysql中若是要用別名的話,須要使用as關鍵字 ,後面跟着別名就好了....Oracle能夠省略as關鍵字...

而且,通常地,咱們使用別名都是用雙引號""把別名括起來,Oracle也支持咱們直接寫別名,可是呢,若是咱們不寫雙引號,那麼咱們的別名是不能有空格的

還有一點的是:Oracle的別名是不能使用單引號來括起來的,Oracle默認認爲單引號是字符串類型和日期類型的。

IO輸入輸出SQL語句

咱們能夠在sqlplus中使用spool命令把SQL語句保存在硬盤中,具體的例子:

spool e:/oracle-day01.sql;

使用spool off命令,保存SQL語句到硬盤文件e:/oracle-day01.sql,並建立sql文件,結束語句

spool off;

固然了,咱們也能夠把硬盤中的SQL文件在sqlplus中執行,只要如下的命令就好了:

@ e:/crm.sql;

轉義字符

有的時候,咱們可能會模糊查詢一些數據,可是呢,在名稱中又有一些特殊的字符。那麼咱們就要通過轉義....固然了,若是按照Java的來,就十分簡單了,就寫一個""就能夠了。

那在Oracle中是怎麼樣轉義的呢??咱們來看下面的例子:

查詢員工姓名中含有'_'的員工,使用\轉義符,讓其後的字符迴歸原本意思【like '%\_%' escape '\'】

select * from emp where ename like '%\_%' escape '\';

若是名稱是'單引號呢???那麼兩個單引號表明着一個引號

插入一個姓名叫''的員工
insert into emp(empno,ename) values(2222,'''''');

單行函數與多行函數

首先,咱們要明確一個概念:

  • 單行函數:輸入一個參數,返回一個結果
  • 多行函數:掃描多個參數,返回一個結果....通常地,多行函數和分組函數的概念是差很少的...

Oracle提供了關於字符串函數、日期函數供咱們對數據進行對應的操做,這裏就不一一贅述了,咱們到時候有須要的時候查文檔就好了。

這裏寫圖片描述

單引號出現的地方以下:

  • 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')

GROUP BY 細節

group by 子句的細節:

  • 1)在select子句中出現的非多行函數的全部列,【必須】出如今group by子句中
  • 2)在group by子句中出現的全部列,【可出現可不現】在select子句中

這裏寫圖片描述

舉例子:下面這段代碼是錯誤的!!!

select max(avg(sal)) "部門平均工資的最大值",deptno "部門編號"
    from emp
    group by deptno;

爲啥是錯誤的呢???分組中咱們已經有了deptno字段了,而咱們select 後面跟着也就是多行函數和該字段而已,爲啥就錯了呢?????咱們若是在分組查詢的時候,使用了多行函數嵌套的話,那麼咱們select字段後面只能跟隨着它這麼一個列,而不能再多了。max(avg(sal)) 至關於又分組了一次

固然了,若是咱們僅僅是求出每一個部門的平均工資,也就是下面這段代碼,是徹底沒有問題的:

select avg(sal) "部門平均工資的最大值",deptno "部門編號"
    from emp
    group by deptno;

這裏寫圖片描述


多表查詢、子查詢

當咱們一張表不能把數據查詢出來的時候,就須要鏈接其餘的表一塊兒查詢....

當咱們的查詢條件還沒知道的時候,咱們就可使用子查詢....

通常地,子查詢和多表查詢的功能都是差很少的....

子查詢出來的數據是單行單列的時候,通常咱們都是用等於、大於等於、小於等操做符去限制查詢條件...

若是是單列多行的時候,咱們通常都是用IN、ANY、ALL操做符去篩選條件...

若是是多行多列,咱們就當作該返回查詢結果是一張表【Oracle分頁就是這個原理】


值得注意的是多表查詢的數學基礎是笛卡爾積,也就是說:若是兩張實體表進行鏈接,那麼它會構成一張笛卡爾積表...也就是說:最終就只有一張笛卡爾積表

這裏寫圖片描述

鏈接

在多表查詢的時候,咱們因爲會產生笛卡爾積,因而在笛卡爾積表中會存在不少無關的數據...爲了剔除這些數據,咱們將用到where字句將笛卡爾積表篩選成有用的數據表

通常地,咱們有幾種鏈接:

  • 內鏈接

    • 等值鏈接【使用=號把條件篩選出來】
    • 非等值鏈接【使用between and等手段把條件篩選】
  • 外鏈接
  • 自鏈接

這裏寫圖片描述

這裏寫圖片描述

那如今問題來了,在Oracle中有的功能咱們可使用多表查詢來完成,有的時候咱們又可使用子查詢來完成,那麼咱們通常選擇哪個呢????

咱們看下圖來比較一下他們的優劣:

這裏寫圖片描述

對於索引就是一個以空間換時間的概念..在數據量很大的時候,Oracle會爲咱們的數據建立索引,當掃描數據的時候,就能夠根據索引來直接獲取值....索引的算法也有幾種【二叉樹、稀疏索引、位圖索引....等等】

這裏寫圖片描述

綜上所述:在Oracle中使用多表查詢性能可能比子查詢好一些


Oracle分頁

在講解JDBC的時候,咱們就已經講過Oracle與Mysql的分頁問題了....詳情能夠看個人博文:http://blog.csdn.net/hon_3y/article/details/53790092

咱們在這裏仍是加深一下印象:

Oracle中的分頁是依靠着rownum這個僞列來實現的,因爲rownum只能使用的是<=或者<來獲取數據。。。由於rownum的值可能會常常變【加入一條數據,那麼rownum就+1,講道理rownum能夠是無窮大的,所以不能使用>來進行操做】....

那麼Oracle分頁的思路是這樣子的:

  • 先在子查詢中獲取前n條記錄
  • 因爲返回的是多行多列,所以咱們能夠看作成一張表
  • 那麼將查詢出來的數據放在from字句的後邊
  • 外套的查詢能夠經過where字句來對子查詢出來的數據進行過濾
  • 那麼咱們就能夠查詢出想要的數據了...

公式:

  • Mysql從(currentPage-1)*lineSize開始取數據,取lineSize條數據
  • Oracle先獲取currentPagelineSize條數據,從(currentPage-1)lineSize開始取數據

小面試題

筆試題:有【1000億】條會員記錄,如何用最高效的方式將薪水字段清零,其它字段內容不變?

第一:從emp表中刪除sal字段

  • alter table emp
  • drop column sal;

第二:向emp表中添加sal字段,且內容默認0

  • alter table emp
  • add sal number(6) default 0;

操做表細節

進入回收站
drop table users;

查詢回收站中的對象
show recyclebin;

閃回,即將回收站還原
flashback table 表名 to before drop;
flashback table 表名 to before drop rename to  新表名;

完全刪除users表
drop table users purge;

清空回收站
purge recyclebin;

爲emp表增長image列,alter table 表名 add 列名 類型(寬度) 
alter table emp
add image blob;

修改ename列的長度爲20個字節,alter table 表名 modify 列名 類型(寬度) 
alter table emp
modify ename varchar2(20);

刪除image列,alter table 表名 drop column 列名
alter table emp
drop column image;

重名列名ename爲username,alter table 表名 rename column 原列名 to 新列名
alter table emp
rename column ename to username;

將emp表重命名emps,rename 原表名 to 新表名
rename emp to emps;
  • number(5):

    • 最多5位數字
  • number(6,2):

    • 其中2表示最多顯示2位小數,採用四捨五入,不足位數補0,同時要設置col ... for ...
    • 其中6表示小數+整數很少於6位
    • 其中整數位數不得多於4位,能夠等於4位
  • varchar2(8):

    • 8表示字節

值得注意的是:修改表的時候,是不能回滾的!

Oracle中的級聯操做:

  • 【on delete cascade】級聯刪除
  • 【on delete set null】將外鍵一方設置爲null

若是文章有錯的地方歡迎指正,你們互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠 關注微信公衆號:Java3y
相關文章
相關標籤/搜索