用戶對表或視圖最常進行的操作就是檢索數據,檢索數據可以通過 select 語句來實現,該語句由多個子句組成,通過這些子句完成篩選、投影和連接等各種數據操作,最終得到想要的結果。
語法:
select { [ distinct | all ] columns | * }
[ into table_name ]
from { tables | views | other select }
[ where conditions]
[ group by columns ]
[ having conditions ]
[ order by columns ]
- select子句 :用於選擇數據表、視圖中的列
- into 子句:用於將原表的結構和數據插入新表中
- from 子句:用於指定數據來源,包括表,視圖和其他select 語句。
- where 子句:用於檢索的數據進行篩選
- group by 子句:用於檢索結果進行分組顯示
- having 子句:用於從使用group by子句分組后的查詢結果中篩選數據行
- order by 子句:用來對結果集進行排序(包括升序和降序)
一、簡單查詢
只包含select 子句和 from 子句的查詢就是簡單查詢,同時也是select語句的必選項。
select 子句用於選擇想要在查詢結果中顯示的列,這些列可以用列名來表示,也可以使用星號(*)來表示。查詢數據時,數據將按照select 子句后面指定的列名順序來顯示;如果使用星號,則表示查詢所有的列,這時候按照表結構的自然順序來顯示。
1、檢索所有的列
如果想要檢索知道數據表的所有列,在select 子句后面加星號來實現。
語法: select * from table_name;
注意:a、檢索數據表需要注意是否屬於該模式,如果是模式內部檢索數據,直接使用表名;
b、如果不在指定表所屬的模式內部檢索數據,不僅要查看當前模式是否具有查詢的權限,而且還要在表名前面駕駛所屬的模式名稱
c、 form 后面可以跟多個表名,每個表名直接用逗號隔開即可
2、檢索指定的列
如果想要顯示指定的列而不是全部的列,並且被指定列的順序不受限制,指定部分列也稱為投影操作。需要把所顯示的列緊跟在select 關鍵字后面,每個列名用逗號隔開。
語法:select column_name1,column_name2,column_name3... from table_name;
3、帶有表達式的select 子句
在使用select 語句時,對於數字數據和日期數據都可以使用算數表達式,可以使用算數運算法,包括加、減、乘、除和括號操作。不僅可以執行單獨數學運算,還可以執行單獨的日期運算以及與列名關聯的運算。
語法:select salary*(1+0.1,sal from emp;
4、為列指定列名
為了方便查看查詢結果,可以為需要的列名指定別名。在 Oracle 系統中,可以使用as 關鍵字來指定別名,也可以什么也不用直接指定。
語法: select empno as "員工編號",ename "員工名稱" from emp;
5、顯示不重復記錄
在默認情況下,結果集中包含所有符合查詢條件的數據行,這樣就可能出現重復的數據。在實際應用中,重復的數據可能不會帶來太多的價值,需要去掉重復的記錄,保留唯一記錄即可。使用 distinct 即可實現。
語法: select distince job from emp;
二、篩選查詢
在 select 語句中使用where 子句可以實現對數據行的篩選操作,只有滿足where 子句中的判斷條件才會顯示在結果集中。
語法:
select columns_list from table_name where conditional_expression;
- columns_list:字段列表
- table_name:表名
- conditional_expression:篩選條件表達式
常用的集中篩選情況:
1、比較篩選
可以在 where 子句中使用比較運算符來篩選數據,這樣只有滿足條件的數據行才會被查詢到,主要由下面6中情況:
a、A=B : 比較 A 與 B 是否相等
b、A!B 或 A <>B : 比較 A 與 B 是否不相等
c、A > B : 比較 A 是否大於 B
d、A < B :比較 A 是否小於 B
e、A >= B : 比較 A 是否大於或等於 B
f、A <= B : 比較 A 是否小於或等於 B
除了上面的6種,還有兩個特殊的“比較篩選”操作
g、A { operator }ANY (B) :表示 A 與 B 中的任何一個元素進行operator 運算符的比較,只要有一個比較值為true,就返回數據行
h、A { operator } ALL (B):表示 A 與 B 中的所有元素都進行 operator 運算符的比較,只有與所有元素比較值都為 true,才返回數據行
下面看一個例子:
SQL > select empno,ename,sal from emp where sal <> all (3000,950,800);
表示從emp 表中使用 all 關鍵字過濾工資(sal) 同時不等於300、950和800的數據行。
2、使用特殊關鍵字篩選
SQL 語言提供了 like、in、between 和 isnull 等關鍵字來篩選匹配的數據,下面一項項來看:
(1)Like 關鍵字
在 where 子句中使用 like 關鍵字查詢數據的方式也稱為字符串模式匹配或字符串模糊查詢。like 關鍵字需要使用通配符在字符串內查找指定的模式,常用的通配符有下划線 “_”,代表任意一個字符;百分號 “%”,代表任 意數量的字符。
EG: SQL> select name,job from emp where name like "S%" and job like "K_";
表示從emp表中查詢 名字以 “S” 開頭且任意長度的字符串,並且 job 是以 “K” 開頭長度為 2 的字符串
注意:可以在 like 關鍵字前面加上 not,表示否定的判斷,當然也可以在 in ,between ,isnull 和 isNAN 等關鍵字前面加上 not 來表示否定的判斷。
(2)IN 關鍵字
當測試一個數據值是否匹配一組目標中的一個時,通常用 IN 關鍵字來指定列表搜索條件。
格式: value in (value1,value2,value3......)
EG : SQL > select name from job where name in ("Tom", "Emma","Tony");
表示從emp 表中查詢 名字在列表中的數據行 。
(3)Between 關鍵字
需要返回某一個數據值是否位於兩個給定的值之間,可以使用范圍條件進行查詢。通常使用 between... and 和 not between...and 來指定范圍條件。
使用 between ....and 的條件時,指定的第一個值必須小於第二個值。其實等價於比較運算符(>= ... <=).
EG: SQL > select sal from emp where sal between 2000 and 3000;
表示從emp 表中查詢工資大於等於2000並且小於等於3000的數據行。
(4)ISNULL關鍵字
空值(NUll)從技術上來說就是位置的、不確定的值,但空值與空字符串不同,空值是不存在的值,而空字符串是長度為 0 的字符串。
空值代表的是未知的值,但是並不能用空值來互相比較,這點需要特別注意。
EG: SQL > select address from student where address is null;
表示從 student 表中查詢住址目前為空值的數據行
3、邏輯篩選
使用邏輯運算符 AND、OR、NOT可以進行邏輯篩選,可以把多個篩選條件組合起來,這樣便於獲取更加准確的數據記錄。
AND 表示兩個表達式之間 “邏輯與” 的關系,需要滿足多個兩個或者多個表達式才能成立。
OR 表示兩個表達式“邏輯或” 的關系,兩個表達式中有一個為 true,則這個邏輯表達式的值就為 true。
NOt 表示對表達式執行“邏輯非” 的運算。
三、分組查詢
數據分組的目的是用來匯總數據或為整個分組顯示單行的匯總信息,通常在查詢結果集中使用 group by 子句對記錄進行分組。
語法:
select columns_list from table_name [ where conditional_expression ] group by columns_list [ having contion_expression] ;
- column_list:字段列表,在 group by 子句中也可以指定多個列分組。
- table_name:表名
- condition_expression: 篩選條件表達式。
- having:該子句是對分組的再次篩選,只能用於group by 之后,而且可以使用常用的聚合函數
group by 子句可以基於指定某一列的值講數據集合划分為多個分組,同一組內所有記錄在分組屬性上具有相同值,也可以基於指定多列的值將數據集合划分為多個分組。
EG:SQL > select deptno,job from emp group by deptno,job order by deptno;
表示按照部門編號(deptno) 和職務(job)列進行分組。
group by子句經常和聚合函數一起使用。
EG:SQL > select deptno as 部門編號,avg(sal) as 平均工資 from emp group by deptno;
表示按照部門進行分類,然后計算每一個部門的平均工資。
having子句可以進行再次篩選
EG:SQL > select deptno as 部門編號,avg(sal) as 平均工資 from emp group by deptno having avg(sal) > 200;
表示按照部門進行分組查詢,然后通過having子句直接過濾出平均工資大於200的部門信息。
四、排序查詢
查詢數據時,查詢結果將按照默認的順序排列,往往並不能滿足我們的需求。我們可以使用order by 子句對檢索的結果進行排序。
語法:
select columns_list from table_name [ where conditional_expression ] [ group by columns_list ] [ order by { order_by_expression [ ASC| DESC ] } ] [,...n]
- columms_list: 字段列表,可以通過group by 子句指定多個列分組。
- table_name :表名
- condition_expression: 篩選條件表達式
- order_by-expression: 表示要排序的列名或者表達式。關鍵字 ASC 表示升序排列,默認的排序方式;DESC 表示降序排列。
order by 子句可以根據查詢結果中的一個列或多個列對查詢結果進行排序,並且第一個排序項是最主要的排序依據,剩下的是次要的排序依據。
EG:SQL > select deptno,empno from emp order by deptno ,empno;
表示先按照部門編號進行升序排序,如果有相同項,按照員工編號進行升序排序。
五、多表關聯查詢
在實際應用中查詢數據可能會涉及多個數據表,每個表不是獨立存在的,而是若干個表之間的信息存在一定的關系,當查詢一個表的信息時,很可能需要查詢關聯數據表的信息,這就是多表關聯查詢。
1、表別名
在進行多表查詢時,如果多個表之間存在同名的列,則必須使用表名來限定列的引用。SQL 語言提供了設定表別名的機制,使用簡短的表別名就可以替代原有較長的表名稱,可以大大縮短語句的長度。
EG:SQL > select e.empno as 員工編號,e.ename as 員工名稱, d.dname as 部門 from emp e,dept d where e.deptno = d.deptno and e.job ="Manager";
表示通過部門號(deptno)來管理emp表和dept表,並查詢這兩個表中相關字段的信息。
注意:一旦在from 子句中為表指定了列名,則必須在剩余的子句中都使用表別名。
2、內連接
內連接是常用的多表關聯查詢,使用關鍵字inner join來實現,其中,inner 關鍵字可以省略,使用 join 即代表內聯接。使用內聯接查詢多個表時,必須在 from 子句之后定義一個 on 子句,用來指定兩個表實現內聯接的“連接 條件”。
使用內聯接進行多表查詢時,返回的查詢結果是只包含查詢條件和連接條件的行,消除了與另一個表中任何行不匹配的行。
注意:在內聯接的查詢結果中,所有記錄行都是滿足連接條件的。
語法:
select column_list
from table_name1 [ innter ] join table_name2
on join_condition;
- columns_list : 字段列表
- table_name1 和 table_name2 :兩個要實現內連接的表。
- join_condition: 實現內連接的條件表達式。
EG: SQL > select e.empno as 員工編號, e.ename as 員工名稱,d.dname as 部門 from emp e inner join dept d on e.deptno = d.deptno;
表示通過 deptno 字段來連接emp 表和 dept表,並查詢兩個表中相關的字段。
3、外連接
多表之間進行外連接時,除了返回所有匹配的行外,還會返回一部分或全部不匹配的行,這主要取決於外連接的種類,主要由以下3種:
(1)、左外連接:關鍵字為left Outer join 或 left join
左外聯接的結果集包括 LEFT OUTER子句中指定的左表的所有行,而不僅僅是聯接列所匹配的行。如果左表的某行在右表中沒有匹配行,則在相關聯的結果集行中右表的所有選擇列表列均為空值。
EG:select e.empon,e.ename,e.job,d.deptno,d.dname from emp e left join dept d on e.deptno = d.deptno;
表示從員工表(emp)表中查詢出來所有的記錄並查詢部門表(dept)中兩個deptno值相等的記錄,如果沒有相匹配的行,均為空值。
(2)右外連接:關鍵字為 right outer join 或 right join
右向外聯接是左向外聯接的反向聯接。將返回右表的所有行。如果右表的某行在左表中沒有匹配行,則將為左表返回空值。
EG:select e.empno,e.ename,e.job,d.deptno,d.name from emp e right join dept d on e.deptno = d.deptno;
表示從部門表(dept)中查詢出來所有的記錄,並查詢員工表(emp)表中與之deptno 對應的記錄,如果沒有匹配的行,均為空值。
(3) 完全外連接:關鍵字為 full outer join 或 full join
完整外部聯接返回左表和右表中的所有行。當某行在另一個表中沒有匹配行時,則另一個表的選擇列表列包含空值。如果表之間有匹配行,則整個結果集行包含基表的數據值。
EG:select e.empno,e.ename,e.job,d.deptno,d.dname from emp e full join dept d on e.deptno = d.deptno;
表示查詢兩個表中所有的deptno的記錄,如果對方的表中沒有匹配的行,置為空值。
4、自然連接
自然連接是指在查詢多個表時,Oracle 會將第一個表中的列與第二表中具有相同名稱的列進行自動連接。自然連接中,用戶不需要指定進行連續的列,這個任務由 Oracle 系統西段完成,自然連接使用“Natural join”關鍵字。
EG: select empno,ename,job,dname from emp natural join dept where sal > 200;
表示在emp表中查詢工資(sal)大於2000的記錄,並實現emp表與dept 表的自然連接。
注意:自然連接強制要求表之間必須具有相同的列名稱,但是在實際開發中很少用到。在使用自然連接時,不能為列指定限定詞(即表名或表的別名),否則Oracle 會報錯。
5、自連接
在開發中,用戶可能會擁有“自引用式”的外鍵,是指表中的一個列可以是該表主鍵的一個外鍵。
EG:
6、交叉連接
交叉連接實際上就是不需要任何連接條件的連接,它使用 cross join 關鍵字來實現。
語法: select colums_list from table_name1 cross join table_name2;
- colums_list : 字段列表
- table_name: 兩個實現交叉連接的表名。
交叉連接的執行結果是一個笛卡爾積,這種查詢非常冗余,但可以通過where 子句來過濾出有用的記錄。
圖解:
------------------------------------------------------------------------------------------------------------------------------------------------
表A Id name 表B ID job p_id
1 張三 1 25 1
2 李四 2 36 2
3 王五 3 36 4
a.id與b.p_id存在關系
-----------------------------------------------------------------------------------------------------------------------------------------------
(1)內連接
SQL > select a.*,b.* from a inner join b where a.id=b.p_id;
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 張三 1 25 1
2 李四 2 36 2
----------------------------------------------------------------------------------
(2)左外連接
SQL > select a.*,b.* from a left join b where a.id=b.p_id;
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 張三 1 25 1
2 李四 2 36 2
3 王五 null null null
----------------------------------------------------------------------------------
(3)右外連接
SQL > select a.*,b.* from a right join b where a.id=b.p_id;
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 張三 1 25 1
2 李四 2 36 2
null null 3 36 4
----------------------------------------------------------------------------------
(4)完全連接
SQL > select a.*,b.* from a full join b on a.id=b.p_id
---------------------------------------------------------------------------------
a.Id a. name b.id b.job b.p_id
1 張三 1 25 1
2 李四 2 36 2
null null 3 36 4
3 王五 null null null
----------------------------------------------------------------------------------