【摘要】查詢語句是數據庫管理系統中使用最多的語句。查詢語句應用的好壞,將直接關系到數據庫的應用水平和查詢效率。對具有相同查詢條件的SELECT查詢語句一般可有多種不同的表達方法,而不同的表達方法又會使數據庫系統的響應速度大相徑庭;對一個單表的查詢一般比較簡單,但對多表的查詢往往比較復雜,需要一定的方法和技巧。本文深入討論了在大型數據庫Oracle中,怎樣正確地使用多表查詢;如何通過合理、靈活的編寫SQL語句來優化查詢,進一步提高查詢效率,使系統性能得到更加充分、有效的改善和提高。
【關鍵詞】數據庫;多表;查詢;檢索;性能
0引言
一個表由于要受到多方面的限制,表中的列數不可能任意設置。因此,很多情況下所需的信息在一個表中往往是不夠的;我們必須同時對多個相關的表進行查詢。對多表查詢主要有兩種方式:連接和子查詢。
1連接查詢
連接就是把兩個或多個不同表中相關的記錄連在一起,形成一個跨表的大記錄;同時連接也是一種選擇,即選擇出滿足連接條件的記錄。
當對多個表建立連接時,每個表中必須選擇一個列作為連接公共列,這些列的值必須具有良好的選擇性,并且能很容易匹配和對比;它們的數據類型也必須一致,最好都具有完全相同的數據類型。
數據庫提供的連接類型:相等連接、自連接、不等連接和外連接。
1.1相等連接
相等連接要求參與連接操作的兩個表在連接列上都具有相同的值,連接時,將兩個表中所有行在有關列上進行比較檢查它們是否滿足條件。例如:
SELECT empno,ename,sal,emp.deptno,loc FROM emp,dept
WHERE emp.deptno=dept.deptno AND sal>=1500 ORDER BY loc;
即當兩個表中的deptno列值完全相等時才進行連接。相等連接也叫簡單連接或內連接。
1.2 自連接
連接不僅可以在幾個不同的基表上進行,而且還可以在同一個表上建立自身連接,即將同一個表的不同行連接起來。自連接可以看成是一個表的兩個副本之間進行的連接操作。例如:
SELECT e.empno,e.ename,e.job,p.ename ”P_Name”,p.job ”P_Job”
FROM emp e,emp p
WHERE e.mgr=p.empno AND p.job LIKE ’ANA%’;
1.3不等連接
在連接中使用除運算符為等號(=)之外的其它運算符(!=、<>、<、>、<=、>=、BETWEEN…AND、LIKE)所產生的連接叫不等連接。例如:
SELECT ename,sal,dept.deptno,loc,dname
FROM emp,dept WHERE emp.deptno<>dept.deptno AND sal>3000;
1.4外連接
在以上的連接查詢中,查詢結果中都是滿足連接條件行,而外連接則不然。在外連接中,它不僅包含符合連接條件的行,而且還包括左表(在連接運算符左邊的表,也就是表達式中第一個表)或右表(在連接運算符右邊的表,也就是表達式中左表后面的表;左、右表是根據它們在表達式中先后位置關系而言的)中不滿足條件的行。也就是說,這種連接它只限制其中一個表的行,而不限制另一個表中的行。這種連接在許多情況下非常有用,它是一種重要的連接形式。在數據檢索和統計方面,如果能靈活使用,可以大大降低應用程序的復雜程度和開發人員的工作量,提高應用程序的工作效率。
2子查詢
子查詢又叫嵌套查詢或內查詢,它是指在一條查詢語句(或其它語句)中又包含另一個查詢語句。調用子查詢的查詢叫主查詢或外查詢,子查詢中還可以再調用子查詢形成多級子查詢。從語法上說,子查詢就是用一對括號括起來的特殊表達式,它只是對關系求值;所以,子查詢可以出現在允許有表達式的地方,如在WHERE、HAVING以及FROM子句中。
2.1子查詢的執行過程
在執行帶有子查詢的SELECT語句時系統首先從最內層的子查詢開始,一般簡單的子查詢只要執行一次就可以了,并將子查詢結果返回到外查詢。它是由內層到外層執行的,這時子查詢和外查詢各自獨立、單獨執行;只是外查詢要依賴于子查詢返回的結果。這樣的子查詢叫簡單子查詢。例如:
SELECT ename,sal,deptno FROM emp
WHERE sal>=(SELECT max(sal)FROM emp WHERE deptno=20);
但有一些比較復雜的子查詢卻不是如此,在子查詢中要使用外查詢當前數據行的列值。這種情況下子查詢就不能單獨進行,它必須要依賴于外查詢的檢索結果,這種依賴于外查詢的子查詢稱為相關子查詢。在這樣的查詢中,首先執行外查詢;當外查詢獲取一數據行時,子查詢將使用當前行的某個列值作為檢索條件進行比較,并把其查詢結果返回到外查詢。這時外查詢將根據內查詢返回的結果,來判斷獲取該數據行時WHERE條件是否為真。若為真,該數據行就被選中;否則,該數據行就不滿足查詢條件。然后查詢重復執行,這時子查詢可能要被執行多次。因為外查詢每檢索一行數據,子查詢就要被執行一次。例如:
SELECT * FROM emp
WHERE EXISTS(SELECT deptno FROM dept WHERE emp.deptno=dept.deptno);
2.2子查詢的類型
子查詢的類型有兩種,一種是只返回一個數據行的子查詢,它可使用在WHERE、HAVING以及FROM多個場合;另一種是返回多個數據行的子查詢,它只能在WHERE子句中使用。
2.3單行子查詢
單行子查詢的比較關系符包括:=、>、>=、<、<=、<>或!=。
單行子查詢除了可以放在WHERE子句中,還可以放在HAVING子句中和FROM子句中。
2.4多行子查詢
多行子查詢要使用多行比較操作符,它返回多個數據行。
多行比較操作符包括:IN、ANY、ALL。
3兩種查詢的比較
大多數情況下子查詢都可以寫成連接查詢的形式。那么究竟使用哪一種更好、更有效呢?一般來說由于子查詢的執行過程中需要增加一些附加的操作,而連接不需要。這時連接的速度往往要快于子查詢的速度,所以應優先使用連接方式。
4結束語
在數據庫中,SELECT語句是數據庫中應用和語法最為復雜的語句。但只要抓住SELECT-FROM-WHERE這個查詢“三要素”,其它的子句都是在其基礎上的擴展和修飾;只要掌握了這些,就能靈活運用多表查詢,進一步提高多表查詢的效率,充分發揮數據庫的檢索性能。
參考文獻:
[1]顧誠.Oracle 數據庫系統應用開發[M].北京:電子工業出版社,1998
[2]閃四清.Microsoft SQL Server 2000實用教程[M].北京:人民郵電出版社,2000
[3]Judith S.Bowman,Sandra L.Emerson,Marcy Darnovsky 著,康博譯.SQL實用參考手冊[M].北京:清華大學出版社,2002
[4]何明.從實踐中學習Oracle/SQL[M].北京:清華大學出版社,2004