文章目錄
一、查詢語句概述
1、查詢語句基本語法格式
SELECT [ ALL | DISTINCT ] [ * | [table.* | expr[alias] | view.*] [, [ table.* | expr[alias]]]...]
FROM table [ alias ][ ,table[ alias ] ]...
[ WHERE condition]
[ GROUP BY expr [, expr] ...]
[ HAVING condition]
[ ORDER BY expression [ ASC | DESC ] ]
2、僞表和僞劣
1)僞表dual
SQL的標準語法規定,查詢語句必須至少有2個子句,即SELECT子句和FROM子句, Oracle數據庫中就提供了一個表以便從語法上支持查詢語句的完成,即dual表。
2)僞列
Oracle數據庫爲了增強其功能,提供了一組數據列,這些列是由Oracle數據庫自動創建的,從形式上看這些列與表的普通列沒有什麼區別,但實際上它們並不存儲在表中,可以使用查詢語句從這些列中查詢到數據,但是不能對其進行插入、更新或刪除操作,因爲這些列不是真實的存在於表中,因此稱之爲僞列。
二、單表查詢
1、select子句
1)查詢全部列的數據
在SELECT後使用星號(*)表示將查詢FROM子句中指定表或視圖的所有列。
如果想保證效率,不要使用星號
SELECT * FROM diploma;
--等同於SELECT diplpma_id, diplpma_name FROM diploma
2)查詢指定列的數據
在SELECT子句後加上表或視圖的列名可以從表或視圖的指定列中查詢數據。
SELECT t_id, t_name, t_entertime, t_duty, t_research FROM teacher;
3)使用內置函數
在SELECT子句中使用Oracle數據庫的內置函數,可以對結果列進行處理。
SELECT s_id, s_name, s_classname, NVL(s_duty, '沒有職務') FROM student;
4)使用算數表達式
在SELECT子句中也可以使用算數表達式,以實現對一列或多列的計算。
SELECT s_id, s_name, s_classname, s_chinese+ s_math + s_foreign FROM student;
5)使用常量和連接運算符
在SELECT子句中使用常量可以使結果具有一定的含義,常量與表的列之間通常使用雙豎線(||)來做爲連接運算符,以更清楚地表達返回結果的實際意思(此條是Oracle數據庫的語法,其它數據庫可能有其它規定)。
SELECT '學生學號是:' || s_id 學號,'學生姓名是:' ||s_name 姓名 FROM student;
在SELECT子句中使用常量也有一些特殊的用處,比如下面的代碼:
SELECT 1 FROM student;
1其實就是一個常量,查詢到的所有行的值都是這個常量,這裏可以將常量看做是一個臨時列。從效率上來說,SELECT臨時列>SELECT索引列>SELECT普通列>SELECT *,這是因爲不用查詢Oracle數據庫的數據字典表,因此速度比較快。
6)使用列別名
爲列起別名的方法有2種:
(1)列名 列別名
SELECT t_id 教師編號, t_name 教師姓名, t_research 研究方向 FROM teacher;
(2)列名 AS 列別名
SELECT t_id AS 教師編號, t_name AS 教師姓名, t_research AS 研究方向FROM teacher;
通常情況下,不需要用雙引號("")將列別名括起來,但是以下三種情況,列別名需要使用雙引號引起來:
① 列別名中含有空格時。
② 想讓別名原樣顯示時(不用雙引號則英文字符全部大寫)。
③ 列別名中含有特殊字符時。
2、FROM子句
FROM子句的功能比較簡單,作用就是指定查詢語句的源表,可以指定多個源表,表名之間用逗號隔開。
可以在FROM子句中爲表定義別名,但是在Oracle數據庫中不支持使用AS關鍵字命名錶別名的方法。
爲表列起別名的方法是:表名 表別名
3、WHERE子句
WHERE子句的作用是限定返回的記錄,即返回的記錄必須滿足WHERE子句所指定的條件。
WHERE子句需要使用運算符來完成的查詢條件的指定,下表列出了WHERE子句中可以使用的運算符及其含義。
類別 | 運算符 | 含義 |
---|---|---|
比較運算符 | = | 等於 |
> | 大於 | |
>= | 大於等於 | |
< | 小於 | |
<= | 小於等於 | |
<>、!= | 不等於 | |
範圍運算符 | BEWTEEN AND | 在某個範圍內 |
NOT BEWTEEN AND | 不在某個範圍內 | |
包含運算符 | IN | 在某個集合中 |
NOT IN | 不在某個集合中 | |
字符匹配運算符 | LIKE | 與某個文本匹配 |
NOT LIKE | 與某個文本不匹配 | |
空值判斷運算符 | IS NULL | 是空值 |
IS NOT NULL | 不是空值 | |
邏輯運算符 | AND | 邏輯與 |
OR | 邏輯或 | |
NOT | 邏輯非 |
1)比較運算符
比較運算符可以對兩側的表達式進行比較。使用比較運算符需要注意以下幾點:
字符型及日期時間型的數據需要使用單引號引起來。
日期時間型的數據要求符合格式要求,可以通過查看NLS參數來獲取默認的格式信息。
在Oracle數據庫中,WHERE子句中的條件值是大小寫敏感的。
2)2.BEWTEEN AND和NOT BEWTEEN AND
BEWTEEN AND用於判斷指定的條件項是否位於某個範圍之內,BEWTEEN之後的表達式指定範圍的最小值,AND之後的表達式指定範圍的最大值。必須把最小值放在前面,否則查詢不到正確的結果。比較的數據類型可以是字符型、數值型和日期時間型。
BEWTEEN AND前後都是閉區間,即BEWTEEN A AND B結構包括A和B在內。
3)IN和NOT IN
用來指定條件的集合,當WHERE子句中的列值等於條件集合中的某個值時,才返回相應的記錄。NOT IN表示當WHERE子句中的列值不等於條件集合中的任何一個值時,才返回相應的記錄。可以將條件集合中的數據看做是枚舉類型的數據,因爲這些數據都是離散的,它們可以是字符型、數值型和日期時間型數據,但是集合中所有數據的數據類型必須相同。
4)LIKE和NOT LIKE
LIKE運算符用於字符類型的查詢條件的模糊匹配,以實現模糊查詢的功能,LIKE運算符中可以使用的通配符如下表所示。
通配符 | 含義 |
---|---|
%(百分號) | 用於代替任意數目(可以爲0)的任意字符 |
_(下劃線) | 用於代替一個任意字符 |
SQL中提供了對字符進行轉義的功能,方法是使用ESCAPE關鍵字,後接代表轉義的字符,語法格式:
[NOT] LIKE ‘模糊查詢條件’ ESCAPE '轉義字符‘
除了LIKE運算符中需要使用ESCAPE關鍵字定義轉義字符之外,在某些情況下也需要使用轉義字符來對特殊字符進行處理。
5)空值判斷運算符IS NULL和IS NOT NULL
因爲空值不等於任何值,所以不能使用“= NULL”來判斷一個列上的值是否等於空值,而只能使用IS NULL或IS NOT NULL來判斷一個列上的值是否爲空值。
6)邏輯運算符
邏輯運算符包括AND、OR和NOT,其中AND運算符和OR運算符用於連接多個布爾表達式,NOT運算符用於連接單個布爾表達式。
AND運算符的運算規則是:參與運算的多個布爾表達式如果全爲真則結果爲真,有一個爲假則結果爲假;空值和TRUE進行與運算,返回空值,空值和FALSE進行與運算,返回FALSE。
OR運算符的運算規則是:參與運算的多個布爾表達式如果全爲假則結果爲假,有一個爲真則結果爲真;空值和TRUE進行或運算,返回TRUE,空值和FALSE進行或運算,返回空值。
NOT運算符的運算規則是:如果布爾表達式爲真則結果爲假,如果布爾表達式爲假則結果爲真。
7)運算符優先級
優先級排序 | 運算符類型 | 運算符舉例 |
---|---|---|
1 | 一元運算符 | +(正號),-(負號) |
2 | 算數運算符 | *,\,+,- |
3 | 比較運算符 | =,<>,<,>,<=,>= |
4 | 其他比較運算符 | IS [NOT] NULL,LIKE,[NOT] BETWEEN,[NOT] IN |
5 | 邏輯非 | NOT |
6 | 邏輯與 | AND |
7 | 邏輯或 | OR |
8 | 賦值運算符 | = |
4、DISTINCT關鍵字
DISTINCT關鍵字的作用是在列上篩選出不同的值,即取消重複的行記錄。
對於空值,DISTINCT關鍵字後面指定的列中所有的空值都會被視爲是一個值,也就是會將所有的空值壓縮成一個值。
distinct後面可以跟多個字段,表示聯合唯一去重
5、GROUP BY子句與聚合函數
GROUP BY子句的功能是通過在子句的後面指定的表達式將表中的記錄劃分成若干個組,然後使用聚合函數對每個組的記錄進行數據處理。
聚合函數能夠對一組記錄中的某個列上的值執行計算,並返回單個值。常用的聚合函數有5個,它們分別是:
1)COUNT函數:用於統計某個列中的記錄數。語法格式如下:
COUNT(*):用於計算數據表的所有記錄數。
COUNT([ALL|DISTINCT] 列名或表達式):用於計算某個列或表達式的記錄數,但是不包括含有空值的行。
2)AVG函數:用於計算某個列或表達式的數值的平均數。語法格式如下:
AVG([ALL | DISTINCT] 列名或表達式):其參數表達式應該爲數字類型或者能夠轉化爲數字類型的字符類型的數據。
3)SUM函數:用於計算某個列或表達式的數值的總和。語法格式如下:
SUM([ALL | DISTINCT] 列名或表達式):其參數表達式應該爲數字類型或者能夠轉化爲數字類型的字符類型的數據。
4)MAX函數:用於查找某個列或表達式的數值的最大值。語法格式如下:
MAX(列名或表達式):其參數表達式可以是數字類型、字符類型或日期類型的數據。
5)MIN函數:用於查找某個列或表達式的數值的最小值。語法格式如下:
MIN(列名或表達式):其參數表達式可以是數字類型、字符類型或日期類型的數據。
6、HAVING子句
在使用GROUP BY子句分組之後,如果想對已分的組進行有條件的選擇,可以使用HAVING子句,其功能就是選擇和排除分組,因此HAVING子句又被稱爲分組篩選語句。當使用HAVING子句時,Oracle數據庫按照以下步驟執行:
(1)對記錄分組。
(2)在分組的基礎上使用聚合函數。
(3)輸出與HAVING子句匹配的結果。
HAVING子句與WHERE子句的相同點和區別?(面試題)
HAVING子句與WHERE子句都可以起到過濾數據的作用,但是它們之間有一些區別:
(1)功能不同。這兩個子句都具有篩選數據的功能,但是WHERE子句是對所有的數據進行篩選,HAVING子句則是對分組後的數據進行篩選,因此HAVING子句必須與GROUP BY子句纔有意義。
(2)使用場合不同。HAVING子句只能用於查詢語句中,而WHERE子句則可以用於SELECT、UPDATE、DELETE和INSERT…INTO等語句中。
(3)執行順序不同。WHERE子句的執行順序先於HAVING子句,即在對查詢結果進行分組前就將不符合WHERE子句條件的記錄篩選掉了,然後纔會執行GROUP BY子句,再根據HAVING子句的條件篩選分組數據。
(4)條件表達式的要求不同。HAVING子句中的條件表達式要麼是GROUP BY子句中指定的分組條件,要麼是聚合函數或常量,而WHERE子句中的條件則不受此限制,但是WHERE子句中不能使用聚合函數(實際上還是與執行順序有關)。
(5)有些時候,HAVING子句可以與WHERE子句互換使用,但是效率有所不同。
7、ORDER BY子句
ORDER BY子句的作用就是對查詢的結果集進行排序,以便可以按照用戶的需求顯示數據。
ORDER BY子句的後面可以是表的列名、列的別名、列的序號和表達式。ASC關鍵字表示結果按照升序排列,DESC關鍵字表示結果按照降序排列,默認按照升序對記錄進行排序。如果使用了ORDER BY子句,則ORDER BY子句必須是查詢語句的最後一個子句。
DESC還可以查詢對象表結構:
desc course;
不同數據類型的排序規則(以升序爲例)
(1)數值類型的數據按照數字大小的順序由小到大排列。
(2)日期類型的數據規則是較早的日期在前,較晚的日期在後。例如:“01-1月-11”排在“01-1月-12”之前。
(3)英文字符排列按照字母由小到大的順序排列,且大寫字母排在小寫字母的前面,即按照A-Za-z的順序排列
(4)中文的排序規則。
數據庫服務器或客戶端使用的字符集決定了使用何種語言,而在Oracle數據庫中不同的語言的排序方式各不相同。如果採用的字符集是ZHS16GBK,那麼ORDER BY子句默認的是按照漢字的拼音順序進行排序的;如果採用的是其他字符集(如UTF8),那麼漢字的排序是按照BINARY(二進制編碼)排序的,即按照編碼的大小來排序。
8、查詢語句的執行順序
第一步:執行FROM子句。將FROM子句中的表的記錄全部取出來。
第二步:執行WHERE子句。從第一步產生的記錄中篩選出滿足WHERE子句條件的所有記錄。
第三步:執行GROUP BY子句。按照GROUP BY 子句中的分組原則對第二步產生的記錄進行分組。
第四步:執行HAVING子句。按照HAVING子句中的分組篩選條件從第三步產生的記錄中篩選出滿足條件的所有分組的排序規則排序。
第五步:執行SELECT子句。從第四步產生的記錄中將SELECT子句中指定的列或表達式全部取出來。
第六步:執行DISTINCT操作。將重複的記錄從第五步產生的記錄中刪除。
第七步:執行ORDER BY子句。將第六步產生的記錄按照ORDER BY子句指定的排序規則排序。
三、多表連接查詢
1、 內連接
內連接(INNER JOIN)又稱爲相等連接或簡單連接,就是當兩個或多個表之間存在意義相同列的時候,把這些意義相同的列用“=”運算符連接起來進行比較,只有連接列上值相等的記錄纔會被作爲查詢結果返回。其語法格式如下:
SELECT select_list
FROM table1 [alias], table2 [alias]...
WHERE table1.column = table2.column
[ GROUP BY expr [, expr] ...]
[ HAVING condition]
[ ORDER BY expression [ ASC | DESC ] ]
ANSI爲內連接定義了標準的SQL語法,語法格式如下:
SELECT select_list
FROM table1
[INNER] JOIN table2
ON table1. column = table2.column
WHERE conditions
內連接連接三個數據表的語法格式如下:
SELECT select_list
FROM (table1
[INNER] JOIN table2
ON table1. column = table2.column)
[INNER] JOIN table3
ON table2. column = table3.column)
WHERE conditions
內連接的另外一種形式是使用USING子句,語法格式如下:
SELECT select_list
FROM table1
JOIN table2 USING(column1, column2…);
table1 是驅動表/主表/左表,table2是匹配表/從表/右表。
面試題:內連接的結果集是怎樣的?
驅動表與匹配表之間能互相匹配上的結果組成的集合叫內連接的結果集。
2、外連接
外連接擴充了內連接的功能,把原來被內連接刪除的記錄根據外連接的類型保留了下來。根據保留數據的來源,外連接分爲左外連接、右外連接和全外連接3種。
除了可以使用標準的SQL語法表示外連接外,Oracle數據庫中還可以使用“(+)”運算符來表示一個連接是外連接。注意:無論左外連接還是右外連接,“(+)”都要放在沒有匹配記錄列值就被設置爲空值的表的一端。
1)左外連接
左外連接(left outer join)以左表爲基準,**即使右表中沒有與之相匹配的記錄,也將顯示左表的所有行,但對於右表來說,只能保留與左表匹配的行,未能找到與左表匹配的記錄的列值將被設置爲空值。**語法格式如下:
SELECT select_list
FROM table1,table2
WHERE table1.column = table2.column(+)
面試題:左外連接的結果集是怎樣的?
左表中的所有數據與右表中可匹配上的數據組成的集合叫做左外連接的結果集。右表上其它未匹配上的數據爲空。
ANSI SQL標準的左外連接語法格式如下:
SELECT select_list
FROM table1
LEFT [OUTER] JOIN table2
ON table1.column = table2.column;
2)右外連接
右外連接(right outer join)以右表爲基準,即使左表中沒有與之相匹配的記錄,也將顯示右表的所有行,但對於左表來說,只能保留與右表匹配的行,未能找到與右表匹配的記錄的列值將被設置爲空值,語法格式如下:
SELECT select_list
FROM table1, table2
WHERE table1.column(+) = table2.column
面試題:右外連接的結果集是怎樣的?
右表中的所有數據與左表中可匹配上的數據組成的集合叫做右外連接的結果集。左表上其它未匹配上的數據爲空。
ANSI SQL標準的右外連接語法格式如下:
SELECT select_list
FROM table1
RIGHT [OUTER] JOIN table2
ON table1.column = table2.column;
3)全外連接
全外連接(full outer join)主要功能是返回兩個表連接中滿足等值連接的記錄,以及兩個表中所有等值連接失敗的記錄,也就是說全外連接會把兩個表所有的行都顯示在結果表中,相當於同時做左外連接和右外連接。
如果使用非標準SQL語句做全外連接查詢的話,需要使用UNION運算符將2個連接做集合運算。
ANSI SQL標準的全外連接語法格式如下:
SELECT select_list
FROM table1
FULL [OUTER] JOIN table2
ON table1.column = table2.column;
面試題:怎樣用全外連接、左外連接、右外連接、內連接的結果集相互介紹它們?
- 全外連接包括左外連接和右外連接
- 左外連接包括內連接和右外連接沒有的那一部分
- 右外連接包括內連接和左外連接沒有的那一部分
3、自然連接
自然連接自動使用兩個表中數據類型和值都相同的同名列進行連接,不必爲自然連接手動的添加連接條件,此時的效果和內連接的效果相同。
不同之處在於自然連接只能是同名屬性的等值連接,而內連接可以使用ON或USING子句來指定連接條件。
面試題:內連接和自然連接的相同點和區別?
相同點:自動使用兩個表中數據類型和值都相同的同名列進行連接
不同點:自然連接只能是同名屬性的等值連接,而內連接可以使用ON或USING子句來指定連接條件。
自然連接的語法形式如下:
SELECT select_list
FROM table1
NATURAL JOIN table2;
4、笛卡爾積和交叉連接
如果在連接查詢中沒有指定任何連接條件,那麼查詢結果將是多個表中所有的記錄進行乘積操作得到的結果。
沒有使用WHERE子句的連接查詢又稱爲交叉連接(CROSS JOIN),得到的查詢的結果也是笛卡爾積。
ANSI SQL標準的交叉連接語法格式如下:
SELECT select_list
FROM table1
CROSS JOIN table2;
5、自連接
自連接(self join)就是一個表自己連接自己以實現獲取特定數據的目的。從查詢的角度來看,自連接的FROM子句中的表都是同一個表,只是在做連接的時候把它們視爲不同的數據源來匹配對應的連接條件。
四、子查詢
1、可以使用子查詢的語句
子查詢通常用於查詢語句的WHERE子句中,但是也可以用於查詢語句的其他子句中,如SELECT子句、FROM子句(該類子查詢又稱爲內聯視圖)、GROUP BY子句、HAVING子句、ORDER BY子句或其他子查詢中,還可以用於數據操縱語言和數據定義語言中,如INSERT語句、UPDATE語句、DELETE 語句和CREATE TABLE語句中。任何允許使用表達式的地方都可以使用子查詢。
2、子查詢的分類
1)單行單列子查詢
子查詢只返回一行數據中某一列上的值,即只返回單個值。如果主查詢使用單行單列子查詢返回的結果作爲查詢條件,則應該使用單行運算符進行比較,如>、>=、<、<=、=、<>、!=等。
2)單行多列子查詢
單行多列子查詢返回一行數據中多列上的值。
3)多行單列子查詢
多行單列子查詢返回多行數據,但是列數只有一列,如果主查詢使用多行單列子查詢返回的結果作爲查詢條件,則應該使用能夠處理多個條件的運算符,常用的多條件運算符包括:IN、ANY和ALL。
IN:和前面介紹的功能相同,含有IN運算符的WHERE子句判斷比較列或表達式是否與子查詢結果中的任意一個值相同,如果相同則返回true,否則返回false。
ANY或SOME:表示任意的含義,即含有ANY或SOME運算符的WHERE子句中的比較列或表達式與子查詢結果中的每一個值進行比較,只要有一個值滿足則返回true,如果都不滿足則返回false。
ALL:表示所有的的含義,即含有ALL運算符的WHERE子句中的比較列或表達式與子查詢結果中的每一個值進行比較,只有全部滿足才能返回true,否則返回false
4)多行多列子查詢
多行多列子查詢返回多個行上的多個列值,與單行多列子查詢很相似,只是單行子查詢只能使用單行比較運算符,多行子查詢需要使用多行運算符。
3、相關子查詢
在一些子查詢中,如果想完成子查詢中的查詢操作,必須使用外部主查詢語句的某些列,這類依賴於外部主查詢的子查詢被稱爲相關子查詢(Correlated Subquery)。
相關子查詢的執行方式與普通的子查詢有所不同,相關子查詢是重複執行的,爲主查詢可能選擇的每一行均執行一次子查詢。
在相關子查詢中,使用頻率很高的關鍵字就是EXISTS和NOT EXISTS,它們的功能是用來判斷查詢的結果集中是否存在元素,EXISTS A表示當結果集A不爲空時返回true,爲空時返回false;NOT EXISTS A表示當結果集A爲空時返回爲true,不爲空時返回false。NOT EXISTS因爲運算方法與NOT IN不同,只會返回true或false,不會返回空值,所以不需要考慮子查詢去除空值的問題。
在很多情況下可以將EXISTS和IN、NOT EXISTS和NOT IN互換使用。
面試題:EXISTS和IN、NOT EXISTS和NOT IN是否可以互換?
EXISTS和IN可以互換,但是NOT EXISTS和NOT IN互換是有條件的,條件是表中數據不能有空值。
五、集合運算
1、並集運算
對兩個或兩個以上的結果集進行並集運算需要使用UNION或UNION ALL運算符。
UNION與UNION ALL的差別是前者會自動去掉並集的重複記錄,而後者不會。
進行集合運算時只要2個類的數據類型相近,Oracle數據庫可以自動進行類型和長度的轉換。
如果使用ORDER BY子句則排序列是第一個查詢中定義的列。
華爲面試題:區分UNION和UNION ALL。
UNION與UNION ALL的差別是前者會自動去掉並集的重複記錄,而後者不會。
2、交集操作
對兩個或兩個以上的結果集進行交集運算需要使用INTERSECT運算符。
3、差集操作
對兩個或兩個以上的結果集進行差集運算需要使用MINUS運算符。差集只返回第一個查詢結果集的行,如果在第二個查詢結果中也存在相同的行,則差集運算返回的結果中將不包含這些行。