天天看點

從零開始學習Oracle之查詢資料

作者:ITPro進化論

資料庫管理系統的一個最重要的功能就是資料查詢,資料查詢不應隻是簡單傳回資料庫中存儲的資料,還應該根據需要對資料進行篩選,以及确定資料以什麼樣的格式顯示。Oracle提供了功能強大、靈活的語句來實作這些操作。

1.基本查詢語句

Oracle從資料表中查詢資料的基本語句為SELECT語句。SELECT語句的基本格式是:

SELECT
      {* | <字段清單>}
      [
          FROM <表1>,<表2>...
          [WHERE <表達式>]
          [GROUP BY <group by definition>]
          [HAVING <expression> [{<operator> <expression>}...]]
          [ORDER BY <order by definition>]
          [LIMIT [<offset>,] <row count>]
      ]
      
SELECT [字段1,字段2,…,字段n]
FROM [表或視圖]
WHERE [查詢條件];
           
  • {* | <字段清單>}包含星号通配符選字段清單,表示查詢的字段,其中字段列至少包含一個字段名稱,如果要查詢多個字段,多個字段之間用逗号隔開,最後一個字段後不要加逗号。
  • FROM<表1>,<表2>..,表1和表2表示查詢資料的來源,可以是單個或者多個。
  • WHERE子句是可選項,限定查詢行必須滿足的查詢條件。
  • GROUP BY <字段>,該子句告訴 Oracle如何顯示查詢出來的資料,并按照指定的字段分組。
  • ORDER BY <字段>,該子句告訴Oracle按什麼樣的順序顯示查詢出來的資料,可以進行的排序有:升序(ASC)、降序(DESC)。
  • LIMIT [<offset>,] <row count>,該子句告訴Oracle每次顯示查詢出來的資料條數。

2.單表查詢

單表查詢是指從一張資料表中查詢所需的資料。單表查詢中的各種基本的查詢方式,主要有:查詢所有字段、查詢指定字段、查詢指定記錄、查詢空值、多條件查詢、對查詢結果進行排序等。

2.1查詢所有字段

在SELECT語句中使用星号”*”通配符查詢所有字段;

SELECT * FROM 表名;
           

注意:一般情況下,除非需要使用表中所有的字段資料,最好不要使用通配符“*”。使用通配符雖然可以節省輸入查詢語句的時間,但是擷取不需要的列資料通常會降低查詢和所使用的應用程式的效率。通配符的優勢是,當不知道所需要的列的名稱時,可以通過它擷取它們。

2.2查詢指定字段

查詢表中的某一個字段,文法格式為:

SELECT 列名 FROM 表名;
           

查詢多個字段,文法格式為:

SELECT 字段名1,字段名2,…,字段名n FROM 表名;
           

注意:Oracle中的SQL語句是不區分大小寫的,是以SELECT和select作用是相同的,但是,許多開發人員習慣将關鍵字使用大寫,而資料列和表名使用小寫,讀者也應該養成一個良好的程式設計習慣,這樣寫出來的代碼更容易閱讀和維護。

2.3查詢指定記錄

資料庫中包含大量的資料,根據特殊要求,可能隻需要查詢表中的指定資料,即對資料進行過濾。在SELECT 語句中,通過WHERE子句可以對資料進行過濾,文法格式為:

SELECT 字段名1,字段名2,…,字段名n
FROM 表名
WHERE 查詢條件
           

2.4帶IN關鍵字的查詢

IN操作符用來查詢滿足指定範圍内的條件的記錄,使用IN操作符,将所有檢索條件用括号括起來,檢索條件之間用逗号分隔開,隻要滿足條件範圍内的一個值即為比對項。相反的,可以使用關鍵字NOT來檢索不在條件範圍内的記錄。

2.5帶BETWEEN AND的範圍查詢

BETWEENAND用來查詢某個範圍内的值,該操作符需要兩個參數,即範圍的開始值和結束值,如果字段值滿足指定的範圍查詢條件,則這些記錄被傳回。BETWEEN比對範圍中所有值,包括開始值和結束值。

BETWEEN AND操作符前可以加關鍵字NOT,表示指定範圍之外的值,如果字段值不滿足指定的範圍内的值,則這些記錄被傳回。

2.6帶LIKE的字元比對查詢

通配符是一種在SQL的WHERE條件子句中擁有特殊意思的字元,SQL語句中支援多種 通配符,可以和LIKE一起使用的通配符有“%”和“_”。

  • 百分号通配符“%”,比對任意長度的字元,甚至包括零字元;
  • 下劃線通配符“_”,一次隻能比對任意一個字元。

2.7查詢空值

建立資料表的時候,設計者可以指定某列中是否可以包含空值(NULL)。空值不同于0,也不同于空字元串。空值一般表示資料未知、不适用或将在以後添加資料。在SELECT語句中使用IS NULL子句,可以查詢某字段内容為空記錄。與IS NULL相反的是NOT IS NULL,該關鍵字查找字段不為空的記錄。

2.8帶AND的多條件查詢

使用SELECT查詢時,可以增加查詢的限制條件,這樣可以使查詢的結果更加精确。Oracle在WHERE子句中使用AND操作符限定隻有滿足所有查詢條件的記錄才會被傳回。可以使用AND連接配接兩個甚至多個查詢條件,多個條件表達式之間用AND分開。

2.9帶OR的多條件查詢

與AND相反,在WHERE聲明中使用OR操作符,表示隻需要滿足其中一個條件的記錄 即可傳回。OR也可以連接配接兩個甚至多個查詢條件,多個條件表達式之間用OR分開。 OR操作符和IN操作符使用後的結果是一樣的,它們可以實作相同的功能。但是,IN操作符使得檢索語句更加簡潔明了,并且IN執行的速度要快于OR。

注意:OR可以和AND一起使用,但是在使用時要注意兩者的優先級,由于AND的優先級高于OR,是以先對AND兩邊的操作數進行操作,再與OR中的操作數結合。

2.10查詢結果不重複

在SELECT語句中,可以使用DISTINCT關鍵字訓示Oracle消除重複的記錄值。文法格式為:

SELECT DISTINCT 字段名 FROM 表名;
           

2.11對查詢結果排序

Oracle可以通過在SELECT語句中使用ORDER BY子句,對查詢的結果進行排序。

  • ORDER BY 字段 或者 ORDER BY 字段 ASC 按字段進行升序排序
  • ORDER BY 字段 DESC 按字段進行降序排序
  • 如對多列進行排序,将字段用逗号隔開即可:ORDER BY 字段1,字段2,...字段n

在對多列進行排序的時候,首先排序的第一列必須有相同的列值,才會對第二列進行排序。如果第一列資料中所有值都是唯一的,将不再對第二列進行排序。

2.12分組查詢

分組查詢是對資料按照某個或多個字段進行分組,Oracle中使用GROUP BY關鍵字對資料進行分組,基本文法形式為:

[GROUP BY字段] [HAVING <條件表達式>]
           

其中,“字段”為進行分組時所依據的列名稱;“HAVING <條件表達式>”指定滿足表 達式限定條件的結果将被顯示。

GROUP BY關鍵字通常和集合函數一起使用,如MAX()、MIN()、COUNT()、SUM()、AVG()。

Oracle 可以在GROUP BY子句中使用LISTAGG()函數,将每個分組中各個字段的值顯示出來。

GROUP BY可以和HAVING一起限定顯示記錄所需滿足的條件,隻有滿足條件的分組才會被顯示。

注意:HAVING關鍵字與WHERE關鍵字都可以用來過濾資料,兩者的差別是:HAVING在資料分組之後進行過濾來選擇分組,而WHERE在分組之前用來選擇記錄。另外,WHERE排除的記錄不再包括在分組中。

在GROUP BY子句中使用ROLLUP關鍵字之後,在所有查詢出的分組記錄之後增加一條記錄,該記錄計算查詢出的所有記錄的總和,即統計記錄數量。

使用GROUP BY可以對多個字段進行分組,GROUP BY關鍵字後面跟需要分組的字段,Oracle根據多字段的值來進行層次分組,分組層次從左到右,即先按第1個字段分組,然後在第1個字段值相同的記錄中,再根據第2個字段的值進行分組,……,依此類推。

當使用ROLLUP時,不能同時使用ORDER BY子句進行結果排序,即ROLLUP和ORDER BY是互相排斥的。

2.13使用ROWNUM限制查詢結果的數量

SELECT傳回所有比對的行,有可能是表中所有的行,如果僅需要傳回第一行或者前幾行,則可以使用ROWNUM來限制。

注意:使用ROWNUM時,隻支援<、<=和!=符号,不支援>、>=、=和BETWEEN...AND符号。

3.使用聚合函數查詢

有時候并不需要傳回實際表中的資料,而隻是對資料進行總結。Oracle提供一些查詢功能,可以對擷取的資料進行分析和報告。這些函數的功能有:計算資料表中記錄行數的總數、計算某個字段列下資料的總和,以及計算表中某個字段下的最大值、最小值或者平均值。

從零開始學習Oracle之查詢資料

3.1 COUNT()函數

COUNT()函數統計資料表中包含的記錄行的總數,或者根據查詢結果傳回列中包含的資料行數。其使用方法有兩種:

  • COUNT(*)計算表中總的行數,不管某列是否有空值。
  • COUNT(字段名)計算指定列下總的行數,計算時将忽略空值的行。

3.2 SUM()函數

SUM()是一個求總和的函數,傳回指定列值的總和。

SUM()可以與GROUP BY一起使用,用來計算每個分組的總和。

SUM()函數在計算時,忽略列值為NULL的行。

3.3 AVG()函數

AVG()函數通過計算傳回的行數和每一列資料的和,求得指定列資料的平均值。

AVG()可以與GROUP BY一起使用,用來計算每個分組的平均值。

AVG()函數使用時,其參數為要計算的列名稱,如果要得到多個列的多個平均值,則需要在每一列上使用AVGO函數。

3.4 MAX()函數

MAX()傳回指定列中的最大值。

MAX()也可以和GROUP BY關鍵字一起使用,求每個分組中的最大值。

MAX()函數不僅适用于查找數值類型,也可應用于字元類型。

3.5 MIN()函數

MIN()傳回查詢列中的最小值。

MIN()也可以和GROUP BY關鍵字一起使用,求出每個分組中的最小值。

MIN()函數與MAX()函數類似,不僅适用于查找數值類型,也可應用于字元類型。

4.連接配接查詢

連接配接查詢是關系資料庫中最主要的查詢,主要包括内連接配接、外連接配接等。通過連接配接運算符可以實作多個表查詢。在關系資料庫管理系統中,建立表時各資料之間的關系不必确定,常把一個實體的所有資訊存放在一個表中。當查詢資料時,通過連接配接操作查詢出存放在多個表中的不同實體的資訊。當兩個或多個表中存在相同意義的字段時,便可以通過這些字段對不同的表進行連接配接查詢。

從零開始學習Oracle之查詢資料

4.1内連接配接查詢

内連接配接(INNER JOIN)使用比較運算符進行表間某(些)列資料的比較操作,并列出這些表中與連接配接條件相比對的資料行,組合成新的記錄。也就是說,在内連接配接查詢中,隻有滿足條件的記錄才能出現在結果關系中。

如果在一個連接配接查詢中,涉及的兩個表都是同一個表,這種查詢稱為自連接配接查詢。自連接配接是一種特殊的内連接配接,它是指互相連接配接的表在實體上為同一張表,但可以在邏輯上分為兩張表。

SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name=table2.column_name;
--或者
SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name=table2.column_name;
           

INNER JOIN 與 JOIN 是相同的,取的是兩個表的并集。

從零開始學習Oracle之查詢資料

4.2外連接配接查詢

連接配接查詢将查詢多個表中相關聯的行,内連接配接時,傳回查詢結果集合中的僅是符合查詢條件和連接配接條件的行。但有時候需要包含沒有關聯的行中的資料,即傳回查詢結果集合中的不僅包含符合連接配接條件的行,而且還包括左表(左外連接配接或左連接配接)、右表(右外連接配接或右連接配接)或兩個邊接表(全外連接配接)中的所有資料行。外連接配接分為左外連接配接和右外連接配接。

  • LEFT JOIN(左連接配接):傳回包括左表中的所有記錄和右表中連接配接字段相等的記錄。
  • RIGHT JOIN(右連接配接):傳回包括右表中的所有記錄和右表中連接配接字段相等的記錄。
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;

SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;
           
從零開始學習Oracle之查詢資料
從零開始學習Oracle之查詢資料

4.3複合條件連接配接查詢

複合條件連接配接查詢是在連接配接查詢的過程中,通過添加過濾條件,限制查詢的結果,使查詢的結果更加準确。

5.子查詢

子查詢指一個查詢語句嵌套在另一個查詢語句内部的查詢,在SELECT子句中先計算子查詢,子查詢結果作為外層另一個查詢的過濾條件,查詢可以基于一個表或者多個表。子查詢中常用的操作符有ANY(SOME)、ALL、IN、EXISTS。子查詢可以添加到SELECT、UPDATE和DELETE語句中,而且可以進行多層嵌套。子查詢中也可以使用比較運算符,如“<”、“<=”、“>”、“>=”和“!=”等。

5.1帶ANY、SOME關鍵字的子查詢

ANY和SOME關鍵字是同義詞,表示滿足其中任一條件,它們允許建立一個表達式對子查詢的傳回值清單進行比較,隻要滿足内層子查詢中的任何一個比較條件,就傳回一個結果作為外層查詢的條件。

ANY關鍵字接在一個比較操作符的後面,表示若與子查詢傳回的任何值比較為TRUE,則傳回TRUE。

SELECT numl FROM table1 WHERE
num1 > ANY (SELECT num2 FROM table2);
           

上面SQL語句的意思是将table1中的num1與ANY後的子查詢查出的table2中的num2進行比較,顯示num1>num2的結果。

5.2帶ALL關鍵字的子查詢

ALL關鍵字與ANY和SOME不同,使用ALL時需要同時滿足所有内層查詢的條件。

ALL 關鍵字接在一個比較操作符的後面,表示若與子查詢傳回的所有值比較為TRUE,則傳回TRUE。

SELECT numl FROM table1 WHERE
num1 > ALL (SELECT num2 FROM table2);
           

上面SQL語句的意思是将table1中的num1與ALL後的子查詢查出的table2中的num2的所有值進行進行比較,顯示大于所有num2列值的num1。

5.3帶EXISTS關鍵字的子查詢

EXISTS關鍵字後面的參數是一個任意的子查詢,系統對子查詢進行運算以判斷它是否傳回行,如果至少傳回一行,那麼EXISTS的結果為TRUE,此時外層查詢語句将進行查詢;如果子查詢沒有傳回任何行,那麼EXISTS 傳回的結果是FALSE,此時外層查詢語句将不進行查詢。

NOT EXISTS與EXISTS使用方法相同,傳回的結果相反。子查詢如果至少傳回一行,那麼NOT EXISTS的結果為FALSE,此時外層查詢語句将不進行查詢;如果子查詢沒有傳回任何行,那麼NOTEXISTS傳回的結果是TRUE,此時外層語句将進行查詢。

EXISTS和NOTEXISTS的結果隻取決于是否會傳回行,而不取決于這些行的内容,是以這個子查詢輸入清單通常是無關緊要的。

SELECT numl FROM table1 WHERE
num1 > EXISTS (SELECT num2 FROM table2 where num2=1);
           

上面SQL語句的意思是查詢table2中num2列是否存在為1的值,如果存在則執行table1的查詢語句,如果不存在,則不執行 EXISTS 之前的查詢語句。

5.4帶IN關鍵字的子查詢

IN關鍵字進行子查詢時,内層查詢語句僅僅傳回一個資料列,這個資料列裡的值将提供給外層查詢語句進行比較操作。

SELECT語句中可以使用NOT IN關鍵字,其作用與IN正好相反。

SELECT numl FROM table1 WHERE
num1 in (SELECT num2 FROM table2);
           

6.合并查詢結果

利用UNION關鍵字,可以給出多條SELECT語句,并将它們的結果組合成單個結果集。合并時,兩個表對應的列數和資料類型必須相同。各個SELECT 語句之間使用UNION 或UNION ALL關鍵字分隔。UNION不使用關鍵字ALL,執行的時候删除重複的記錄,所有傳回的行都是唯一的;使用關鍵字ALL的作用是不删除重複行也不對結果進行自動排序。基本文法如下:

SELECT column,... FROM tablel
UNION [ALL]
SELECT column,... FROM table2
           

UNION從查詢結果集中自動去除了重複的行,如果要傳回所有比對行,而不進行删 除,可以使用UNION ALL。

UNION和UNION ALL的差別:使用UNION ALL的功能是不删除重複行,加上ALL關 鍵字語句執行時所需要的資源少,是以盡可能地使用它,是以知道有重複行但是想保留這些行,确定查詢結果中不會有重複資料或者不需要去掉重複資料的時候,應當使用UNION ALL以提高查詢效率。

7.為表和字段取别名

當表名字很長或者執行一些特殊查詢時,為了友善操作或者需要多次使用相同的表時,可以為表指定别名,用這個别名替代表原來的名稱。為表取别名的基本文法格式為:

表名 [AS] 表别名
           

Oracle 可以指定列别名,替換字段或表達式。為字段取别名的基本文法格式為:

列名 [AS] 列别名
           

表别名隻在執行查詢的時候使用,并不在傳回結果中顯示,而列别名定義之後,将傳回給用戶端顯示,顯示的結果字段為字段列的别名。

8.使用正規表達式查詢

正規表達式通常被用來檢索或替換那些符合某個模式的文本内容,根據指定的比對模式比對文本中符合要求的特殊字元串。例如,從一個文本檔案中提取電話号碼,查找一篇文章中重複的單詞或者替換使用者輸入的某些敏感詞語等,這些地方都可以使用正規表達式。正規表達式強大而且靈活,可以應用于非常複雜的查詢。

Oracle中使用REGEXP LIKEO函數指定正規表達式的字元比對模式,下表列出了 REGEXP LIKE函數中常用字元比對清單。

從零開始學習Oracle之查詢資料

--查詢表中name列以字母b開頭的資料

SELECT * FROM table WHERE REGEXP_LIKE(name , '^b');