【oracle數據庫】最全最詳細的數據庫查詢——我的oracle學習之路

前言


必讀在前言這我們先了解下查詢的基本情況,這是一篇關於查詢的文章,你想要知道的查詢知識都在這!如果嫌文章字多,可以根據目錄跳轉快速閱讀!!!


查詢是數據的一個重要操作。用戶發送查詢請求,經編譯軟件變異成二進制文件供服務器查詢,後返回查詢結果集給用戶,查詢會產生一個虛擬表,看到的是表形式顯示的結果,但結果並不真正的存儲,每次執行查詢只是從數據表中提取數據,並按照表的形式顯示出來。

select {[distinct | all ] columns | *}   //<列名>
[into table_name]
from {table | views | other selects}		//<表名>
[where conditions]		//<查詢條件表達式>
[group by columns]		//<分組表達式>
[having columns]		//<分組查詢表達式>
[order by columns]		//<排序的列名> [ASC或DESC]


**執行過程**:from--where -- group by– having– select-- order by
  • select子句:用於選擇數據表、視圖中的列。
  • into子句:用於將原表的結構和數據插入新表中。
  • from子句:用於指定數據來源,包括表、視圖和其他select語句。
  • where子句:用於對檢索的數據進行篩選。
  • group by子句:用於對檢索結果進行分組顯示。
  • having子句:用於從使用group by 子句分組後的查詢結果中篩選數據行。
  • order by子句:用於對結果集進行排序(包括升序和降序)

(對分組查詢的結果進行過濾,要使用having從句。having從句過濾分組後的結果,它只能出現在group by從句之後,而where從句要出現在group by從句之前。where過濾行,having過濾分組。having支持所有where操作符。)


選擇列

選擇表中的列組成結果表,通過select語句的select子句來表示。

查詢所有的列

語法:select * from dept; 
例: select * from dept;  也可以指定多個表   select * from dept,emp;
這裏是說查詢這個表中的所有列。

查詢指定的列

語法: select 列名 from 表名;
例: select empno from emp;   也可以指定多個列  select empno,ename,job from emp;
這裏指定多個列是可以改變列在查詢結果中的默認顯示順序的。

爲列指定別名

語法: select 列名 as "別名" from 表名;
例: select empno as "員工編號",ename as "員工姓名",job as "職務" from emp;
在爲列指定別名時,關鍵字AS是可選項,也可以在列名後直接寫別名。如 empno 員工編號

計算列值

在使用select語句時,對於數字數據和日期數據都可以使用算術表達式,在select語句中可以使用算術運算符,包括加減乘除和括號,另外在select語句中不僅可以執行單獨的數學運算,還可以執行單獨的日期運算以及列名關聯的運算。

select sal*(1+0.1),sal from emp;
檢索EMP表的sal列,把其值調整爲原來的1.1倍。

消除結果集中的重複行

select job from emp;select distinct job from emp;

如此使用distinct關鍵字可以去除結果集中重複的數據,該關鍵字用在select子句的列表前面。


選擇行

選擇行通過where指定條件實現,該子句必須緊跟在from子句之後。

表達式比較

比較運算符用於比較兩個表達式的值,共有7個分別是=(等於)、<(小於)、<=(小於等於)、>(大於)、>=(大於等於)、<>(不等於)、!=(不等於)。當兩個表達式值均不爲空值(NULL)時,比較運算返回邏輯值TRUE(真)或FALSE(假),而當兩個表達式中有一個爲空值或都爲空值時,比較運算將返回UNKNOWN。

例: select empno,ename,sal from emp where sal > 1500;
在SCOTT的模式下查詢eMP表中工資(sal)大於1500的數據記錄.

模糊查詢——like


LIKE用於指出一個字符串是否與指定的字符串相匹配,其運算對象可以是char,varchar2和date類型的數據,返回邏輯值true或false,LIKE運算符可以使用以下兩個通配符

  • “%”代表0或多個字符。
  • “_”代表一個且只能是一個字符。
select empno,ename from emp where ename like 'S%';
例如:“S%”表示以字母S開頭的任意長度的字符串,“%M%”表示包含字母M的任意長度的字符串,“_MRKJ”表示5個字符長度,且後面4個字符是MRKJ的字符串。

tips:
可以在LIKE關鍵字前面加上NOT,表示否定的判斷,如果LIKE爲真,則NOT LIKE爲假


範圍比較

IN關鍵字

在測試一個數據是否匹配一組數據中的一個值時,用IN或NOT IN關鍵字來指定搜索條件

1select empno,ename job from emp where job in ('PRESIDENT','MANAGER');
在emp表中,用in查詢職務爲'PRESIDENT','MANAGER'中任意一種的員工信息。

例2select empno,ename job from emp where job not in ('PRESIDENT','MANAGER');
在emp表中,用 not in查詢職務不在指定目標列表'PRESIDENT','MANAGER'範圍內的員工信息。

BETWEEN關鍵字

需要返回某一個數據值是否位於兩個給定的值之間,可以使用範圍條件進行檢索,通常使用between …and 和not between …and來指定範圍條件。

  • 使用between …and查詢條件時指定的第1個值必須小於第2個值,因爲between …and實質是查詢條件“大於等於第1個值,並且小於等於第2個值”的簡寫形式。即between …and包括兩端的值等價與比較運算符的(>=…<=)
  • 使用not between …and返回某一個數據值在兩個指定值的範圍以外,不包括兩端的值
1select empno,ename,sal from emp where sal between 2000 and 3000;
在eMP表中使用 between and關鍵字查詢工資(sal)2000~3000元之間的員工信息.2select empno,ename,sal from emp where sal not between 2000 and 3000;
在eMP表中使用 not between and關鍵字查詢工資(sal)不在2000~3000元之間的員工信息.

空值比較

首先說明

空值:不存在的值 ≠ 空字符串:長度爲0的字符串

空值代表的是未知的值,並不是所有的空值都相等,比如“student”表中有兩個學生的年齡未知,但是無法證明這兩個學生的年齡相等,這樣就不能用“=”運算符來檢驗空值,這裏用IS NULL關鍵字檢測特殊值之間的等價性,IS NULL關鍵字通常在where子句中使用。

例: select empno,ename,comm from emp where comm is null;
查詢emp表中沒有獎金的員工信息。



子查詢!!!

Oracle子查詢就是嵌套查詢,他把select 查詢的結果作爲另外一個select、update或delete語句的條件,它的本質就是where條件查詢中的一個條件表達式。比如說,判定列值是否與某個查詢的結果集中的值相等,作爲查詢條件一部分的查詢稱爲子查詢,PL/SQL允許select多層嵌套使用,用來表示複雜的查詢。簡單理解就是嵌套,嵌套,嵌套。Insert,update,delete,select語句都可以使用子查詢。

子查詢通常與IN , EXIST 和 比較運算符結合使用。其中我們數據庫開發過程中,子查詢可以根據查詢結果的行數的多少,可以區分爲單行子查詢和多行子查詢。

  • 單行子查詢:向外部返回的結果爲空或者返回一行。

  • 多行子查詢:向外部返回的結果爲空、一行、或者多行。

單行子查詢

單行子查詢是指返回一行數據的子查詢語句,當在where子句中引用單行子查詢時,可以使用單行比較運算符(=,>,<,>=,<=,<>)。

例: select empno,ename,sal from emp 
	where sal > (select min(sal) from emp)
	and sal < (select max(sal) from emp);
	在emp表中查詢既不是最高工資,也不是最低工資的員工信息。

注意:

  • 如果內層子查詢語句的執行結果爲空值,那麼外層where子句就始終不會滿足條件,這樣該查詢的結果就必然爲空值,因爲空值無法參與比較運算。
  • 在執行單行子查詢時,要注意子查詢的返回結果必須是一行數據,否則提示報錯無法執行。另外子查詢中也不能包含order by,如果要對數據進行排序的話,那麼只能在外層查詢語句中使用order by子句。

多行子查詢

多行子查詢是指返回多行數據的子查詢語句,當在where子句中使用多行子查詢時,必須使用多行比較符IN ANY ALL。

IN運算符

使用IN運算符時,外查詢會和子查詢結果集的每一個結果進行匹對,只有一個匹對上了,那麼外查詢就返回當前的檢索的記錄。

例: select empno,ename,job from emp
	 where deptno in (select deptno from dept where dept.dname <> 'SALES');
	在emp表中查詢不是銷售部門的員工信息。
ANY運算符

ANY運算符必須與單行操作符結合使用,並且返回行只要匹配子查詢的任何一個結果即可。

例: select deptno,ename,sal from emp
     where sal > any
	(select sal from emp where deptno = 10) and deptno <> 10;
	在eMP表中查詢工資大於部門編號爲10的任意一個員工工資的其他部門的員工信息。

ALL運算符


ALL運算符必須與單行操作符結合使用,並且返回行必須匹配所有的子查詢的結果。

例: select deptno,ename,sal from emp
	where sal > all
	(select sal from emp where deptno = 30);
	在eMP表中查詢公司大於部門編號爲30的所有員工工資的員工信息。

關聯子查詢


單行和多行子查詢,內層和外層查詢是分開執行的,沒有任何關係,外層僅僅是用內層的結果作爲一個條件。而關聯子查詢是指內查詢和外查詢是相互關聯的,內查詢的執行需要藉助於外查詢,而外查詢的執行又離不開內查詢的執行。

例: select empno,ename,sal from emp a
	where sal > (select avg(sal) from emp where job = a.job)
	order by job;
	在eMP表中使用關聯子查詢檢索工資大於同職位的平均工資的員工信息。

解釋:

在上面的查詢語句中,內查詢使用關聯子查詢計算每個職位的平均工資,而關聯子查詢必須知道職位的名稱,這個時候,外查詢就使用a.job爲內存查詢提供職位名稱,來計算出某個職位的平均工資,如果外查詢正在檢索的數據行高於平均工資,那麼這一行的員工信息會顯示出來,否則不顯示。


Tips:在執行關聯子查詢過程中,必須遍歷數據表中的每一條記錄,因此如果被遍歷的數據中有大量的數據記錄,則關聯子查詢的執行速度會比較緩慢


連接(多表聯查)

我們在學習或者開發中會設計很多數據表,每個表的信息不是獨立存在的,而是存在一定的關係,這樣當用戶查詢某一個表的信息時,很可能需要查詢關聯數據表的信息,這就是多表關聯查詢。多表聯查要比單表查詢複雜的多,在進行多表關聯查詢時可能會涉及內連接外連接,自然連接,自連接,交叉連接等概念,下面我們對這些內容進行講解。


多表連接基本查詢

使用一張以上的表做查詢就是多表查詢。

語法: SELECT {DISTINCT} *|列名.. FROM 表名 別名,表名 1 別名

		{WHERE 限制條件 ORDER BY 排序字段 ASC|DESC...}
		
例:查詢員工表和部門表。
select * from emp,dept;

在這裏插入圖片描述

我們發現產生的記錄數是 56 條,我們還會發現 emp 表是 14 條,dept 表是 4 條,56 正是 emp表和 dept 表的記錄數的乘積,我們稱其爲笛卡爾積。

如果多張表進行一起查詢而且每張表的數據很大的話笛卡爾積就會變得非常大,對性能造成影響,想要去掉笛卡爾積我們需要關聯查詢。在兩張表中我們發現有一個共同的字段是 depno,depno 就是兩張表的關聯的字段,我們可以使用這個字段來做限制條件,兩張表的關聯查詢字段一般是其中一張表的主鍵,另一張表的外鍵。

select * from emp,dept where emp.deptno = dept.deptno;

在這裏插入圖片描述
關聯之後我們發現數據條數是 14 條,不在是 56 條。

多表查詢我們可以爲每一張表起一個別名

select * from emp e,dept d where e.deptno = d.deptno;

在這裏插入圖片描述

內連接

內連接是一種常用的多表聯查方式,一般使用inner join來實現,其中inner關鍵字可以省略。內連接簡單說就是用join指定連接兩個表,用on指定連接的條件。如果進一步限制查詢的範圍,可以直接在後面添加where子句。


select 字段 from1 [inner] join2 on 連接條件

例: select e.empno 員工編號, e.ename 員工姓名, d.dname 部門
	from emp e join dept d on e.deptno = d.deptno;
	在scott的模式下,通過deptno字段來實現連接eMP表和depat表,並檢索這兩個表中相關字段的信息.

在這裏插入圖片描述

外連接

使用內連接進行查詢的時候,返回的結果只包含符合查詢條件和連接條件的行,內連接消除了與另一個表中的任何行不匹配的行,而外連接擴展了內連接的結果集,除了返回所有匹配的行之外,還會返回一部分或者全部不匹配的行。

  • 左外連接:關鍵字left outer join 或者 left join
  • 右外連接:關鍵字right outer join或者 right join
  • 完全外連接:關鍵字full outer join 或者full join

左外連接

左外連接的查詢結果中,不僅包含了滿足連接條件的數據行,還包含了左表中不滿足連接條件的數據行。

例: select e.empno,e.ename,e.job,d.deptno,d.dname
	from emp e left join dept d
	on e.deptno = d.deptno;
	EMP表和depat表之間通過deptno列進行左外連接。

在這裏插入圖片描述


我們可以看到圖中的null值被記錄在結果集中,這說明左外連接的查詢結果中,會包含左表中不滿足連接條件的數據行。


右外連接

那麼對於右外連接也是同樣的道理,右外連接的查詢結果中不僅包含了滿足連接條件的數據行,而且還包含了右表中不滿足連接條件的數據行。

例: select e.empno,e.ename,e.job,d.deptno,d.dname
	from emp e right join dept d
	on e.deptno = d.deptno;
	在scott的模式下實現emp表和dept表之間通過deptno列進行右外連接。

在這裏插入圖片描述

從表中我們可以看到,雖然部門編號爲40的部門,現在在emp表中還沒有員工記錄,但是它卻出現在查詢結果中,這說明右外連接的查詢結果會包含右表中不滿足連接條件的數據行。


在外連接中,也可以使用外連接的連接運算符“(+) ” 該連接運算符可以放在等號的左邊,也可以放在等號的右邊,但一定要放在缺少相應相應信息的那一邊。


這個+號可以這樣來理解: + 表示補充,即哪個表有加號,這個表就是匹配表。所以加號寫在右表,左表就是全部顯示,故是左連接。

關於使用(+)的一些注意事項:
1.(+)操作符只能出現在where子句中,並且不能與outer join語法同時使用。
2. 當使用(+)操作符執行外連接時,如果在where子句中包含有多個條件,則必須在所有條件中都包含(+)操作符
3.(+)操作符只適用於列,而不能用在表達式上。
4.(+)操作符不能與or和in操作符一起使用。
5.(+)操作符只能用於實現左外連接和右外連接,而不能用於實現完全外連接。

完全外連接

oracle會執行一個完整的左外連接和右外連接查詢,然後將查詢結果合併,並消除重複的記錄行。

例: select e.empno,e.ename,e.job,d.deptno,d.dname
	from emp e full join dept d
	on e.deptno = d.deptno;
	在Scott模式下實現emp表和dept表之間通過deptno列進行完全外連接。

在這裏插入圖片描述

自然連接

自然連接是指第1個表的列和第2個表中具有相同名稱的列進行自動連接,這樣就不需要用戶明確的指定進行連接的列。自然連接使用natural join關鍵字。但在我們平常開發或者學習中很少用到自然連接,因爲它必須具有相同的列名稱容,這樣在設計表時容易出現未知的錯誤。

需要注意的是,在使用自然連接時,不能爲列指定限定詞(即表名或表的別名),否則oracle系統中會出現“ORA-25155:NATURAL連接中的使用的列不能有限定詞”的錯誤提示。

自連接

自連接主要用在自參考表上顯示上下級關係或層次關係。自參照表是指在同一張表的不同列之間具有參照關係或主從關係的表。例如emp表包含empno(僱員號)和mgr(管理者號),兩者之間就具有參照關係,這樣用戶就可以通過mgr列與empno列的關係,實現查詢某個管理者所管理的下屬員工信息。


爲了顯示僱員及其管理者之間的對應關係,可以使用自連接,因爲自連接是在同一張表之間的連接查詢,所以必須定義表別名。

 例: select e1.ename 下屬員工, e2.ename 上層管理者
	from emp e2 left join emp e1
	on e2.empno = e1.mgr
	order by e1.mgr;
	在scott模式下,查詢所有管理者所管理的下屬員工信息。

在這裏插入圖片描述

交叉連接


交叉連接實際上就是不需要任何連接條件的連接,使用cross join 關鍵字來實現。他的執行結果是一個笛卡爾積,這種查詢結果是非常冗餘的,但是可以通過where子句來過濾有用的記錄信息。

語法:  selectfrom1 cross join2; 

多表聯查範例


select e.empno,e.ename,
decode(s.grade,1,'一級',2,'二級',3,'三級',4,'四級',5,'五級') grade,
d.dname,e1.empno,e1.ename,
decode(s1.grade,1,'一級',2,'二級',3,'三級',4,'四級',5,'五級') grade
from emp e, emp e1, dept d, salgrade s, salgrade s1
where e.mgr = e1.empno 
and e.deptno = d.deptno
and e.sal between s.losal and s.hisal
and e1.sal between s1.losal and s1.hisal
查詢出每個員工編號,姓名,部門名稱,工資等級和他的上級領導的姓名,工資等級

在這裏插入圖片描述


統計

聚合函數

使用聚合函數可以針對一組數據進行計算,並且得到相應的結果。

  1. 統計記錄數 count()
select count(*) from emp;
查詢出所有員工的記錄數

注意:這裏不建議使用count(*),可以使用一個具體的列以免影響性能,如: select count(ename) from emp;
  1. 最小值查詢 min()
select min(sal) from emp;
查詢員工最低工資
  1. 最大值查詢 max()
select max(sal) from emp;
查詢員工最高工資
  1. 查詢平均值 avg()
select avg(sal) from emp;
查詢員工的平均工資
  1. 求和函數 sum()
select sum(sal) from emp t where t.deptno  = 20;
查詢20號部門的員工的工資總和

group by函數

group by 子句經常與聚合函數一起使用,使用group by子句和聚集函數可以實現對查詢結果中每一組數據進行分類統計。

常用的函數有avg、count、max、min、sum

例: select job,avg(sal),max(sal),sum(sal),count(job)
	from emp
	group by job;
	在emp表中,使用group by子句對工資記錄進行分組,並計算平均工資avg、所有工資的總和sum以及最高工資max和各組的行數。

在這裏插入圖片描述

注意

  1. 在使用group by子句時,在select子句的後面,只可以有兩類表達式:統計函數和進行分組的列名。

  2. 在select子句中的列名必須是進行分組的列,除此之外添加的其他列名都是錯誤的,group by子句後面的列名不可以出現在select詞句中。
    還不懂的看這兒——>group by詳解https://blog.csdn.net/qq_44333320/article/details/106423580

  3. 在默認情況下,將按照group by子句指定的分組列升序排序,如果需要重新排序,可以使用order by子句指定新的排序順序。

having子句


having子句通常與group by子句一起使用,在完成對分組結果統計後,可以使用having子句對分組的結果做進一步的篩選。having子句緊跟着groupby子句後面,如果不使用group by子句,having和where其實功能一樣,區別就是having子句可以使用avg、sum等聚合函數,而where不可以使用。


tips:記住select語句中子句的處理順序,在select語句中,首先由from子句找到數據表,where子句則接收from子句輸出的數據,而having則接收來自group by、where、from子句的輸出。

例: select deptno 部門編號,avg(sal) 平均工資
	from emp 
	group by deptno
	having avg(sal) > 2000;
	在emp表中,首先通過分組的方式計算出每個部門的平均工資,然後再通過having子句過濾出平均工資大於2000的記錄信息。

在這裏插入圖片描述


排序

我們平常在檢索數據的時候,如果說數據從數據庫裏直接讀取出來,這時候查詢它將按照默認的方式排序,這種排序往往不是我們所需要看到的,尤其是數據比較大的時候,我們看起來會非常的麻煩,所以說我們要對檢索的結果進行排序。

語法:
select 字段 fromorder by [ASC | DESC] [,...n]

order by 關鍵字ASC表示升序,也是默認排序;DESC表示降序。order by 子句可以根據查詢結果中的一個列或者多個列進行排序,並且第一個排序項是主要的排序項,其次是次要的排序項。

 例: select deptno,empno,ename from emp order by deptno,empno;
 在Scott模式下,檢索emp表中所有的數據,並按照部門編號,員工編號排序。

在這裏插入圖片描述




希望對你有所幫助!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章