posts - 78, comments - 34, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

                數(shù)據(jù)庫比較枯燥,我說的是使用數(shù)據(jù)庫不是做數(shù)據(jù)庫。總是用SQL語句那么跑來跑去,想把數(shù)據(jù)庫講解的十分有趣,著實不是一件容易的事。只是在PLSQL里編寫SQL語句,然后調(diào)用、查看結(jié)果。雖然數(shù)據(jù)庫很枯燥,但它在項目中的功用卻是十分重要的。我原未如此的深入使用過數(shù)據(jù)庫,近兩天一見,其功能也讓我十分興奮,以前自己寫的小東西,走了些彎路!

           

               無論如何還是要搞好數(shù)據(jù)庫的,尤其是Oracle數(shù)據(jù)庫。明天是最后一天學(xué)習(xí)數(shù)據(jù)庫了,終于要把這塊陣地給解放了!

               OK,來看重點內(nèi)容吧!

           

               常用的分組函數(shù),這個比較重要,在其他數(shù)據(jù)庫中也有:

          1.        AVG,求平均值。如果某一記錄為null,則不加入平均值的計算。(不加入被除數(shù))

          2.        COUNT,求表中所有符合條件的記錄數(shù)。如果某一記錄為null,則不計算在內(nèi)!

          3.        MAX,求最大值。

          4.        MIN,求最小值。

          5.        SUM,求合。

           

          還有一個特殊的函數(shù)NVL,將字段值為空的記錄替換為指定的值,AVG(NVL(commission_pct,0)。比如上面的AVG函數(shù)將null記錄剔除在外。這樣調(diào)用就不會把null值的記錄剔除在外了:NVL(AVG(NVL(commission_pct,0)))

           

          Group by 子句,是最低級的運(yùn)算語句,它被放置在語句的最后,對Group by子句分組的記錄進(jìn)行過濾應(yīng)使用having語句。Where是用于Group by之前的記錄過濾。在Select列表中出現(xiàn)的字段,如果不是在組函數(shù)中,那么它必須也被放置到Group by子句中。

           

          接下來是十分重要的內(nèi)容:多表連接和子查詢

           

          首先讓我們來回顧一下“外鍵”字段,比如有一個部門表,有一個員工表。員工表中使用的部門ID就是一個外鍵,這個部門ID就是部門表中的ID。這樣設(shè)計有益于節(jié)省空間、快速查詢和易于管理等特點。這樣的表查詢的操作比較多,我們應(yīng)該如何實現(xiàn)便利、快速的查詢呢?難道從員工表中取出部門ID然后再到部門表中查詢這個IDNO,這樣太麻煩了,訪問量多了,明顯會使速度降下來。所以表連接出現(xiàn)了!表連接就是將多個表,根據(jù)表之間的相關(guān)字段關(guān)系連接起來,就像一張表一樣。對這一大張表的操作十分方便、快捷!

           

          Oracle的語法,使用表連接從多個表中查詢數(shù)據(jù):

          SELECT          table1.column, table2.column

          FROM                            table1, table2

          WHERE          table1.column1 = table2.column2;

          WHERE 子句中寫入連接條件。

          當(dāng)多個表中有重名列時,必須在列的名字前加上表名作為前綴。

           

          例,查詢員工的姓名和所在部門:

          clip_image002

          其中的ED分別是表EMP和表DEPT的別名,這里不能使用AS

          EMP表中的DEPTNO字段是個外鍵,它指向DEPT表中的DEPTNO

           

          Oracle中都有哪些表連接?在Oracle8i之前有:

          1.        等值連接 – Equijoin,這是連接操作中最常見的一種。通常在存在主外鍵約束條件的多表上建立的,連接中的兩個字段通過等號建立等值關(guān)系。如上面的例子是使用主外鍵對兩個表的連接,還可以對多個表連接,此時可以使用AND增加WHERE子句的連接條件。

          2.        非等值連接 -- Non-equijoin。例,通過EMP表和SALGRADE(薪水等級)表,查詢員工薪水所處等級:

          clip_image004

          語句也可寫成:

          SELECT E.ENAME,E.JOB,S.GRADE

          FROM EMP E,SALGRADE S WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL

          使用JOIN ON語句,更直觀些!它是9i中加入的,可以使用多個JOIN ON語句,連接多個表,它們之間不需要添加任何關(guān)鍵字,比如“AND”。

          3.        外連接 -- Outer join,外連接可以查詢出不滿足條件的記錄,它分為左外連接和右外連接(繼續(xù)關(guān)注下面9i中的外連接)。

          左外連接:

          clip_image006

          正是子句中的“(+)”起的作用,這樣將DEPTNO表中的所有記錄都顯示出來了,即使有沒有員工的部門也顯示了。

          右外連接:

          clip_image008

          正是子句中的“(+)”起的作用,將EMP表中的記錄全部顯示出來了,即使沒有部門的員工也顯示了。

          4.        自連接 -- Self join,就是連接自己。例,取對員工對應(yīng)的領(lǐng)導(dǎo):

          clip_image010

          因為公司所有職員都在一張表中(包括領(lǐng)導(dǎo)),所以為了查找出對應(yīng)員工的領(lǐng)導(dǎo),使用了自連接。自連接就像是為自己創(chuàng)建了一個引用。

           

          Oracle9i時,新增加的連接(SQL1999適應(yīng)性連接):

          1.   交叉連接 -- Cross joins,產(chǎn)生了一個笛卡爾積,就象是在連接兩個表格時忘記加入一個WHERE子句一樣。相互交叉,返回的記錄數(shù)正好是兩個表記錄數(shù)的乘積。轉(zhuǎn)一個兄弟對交叉鏈接的介紹:http://tech.techweb.com.cn/thread-384787-1-1.html

          clip_image012

          上面的語句與這個功效一樣:

          SELECT E.ENAME,E.JOB,D.DNAME

          FROM EMP E,DEPT D

           

          2.   自然連接 -- Natural joins,基于兩個表中列名完全相同的多個列產(chǎn)生連接。從兩個表中選出連接列的值相等的所有行,如果兩個列的名稱相同,但是具有不同的數(shù)據(jù)類型,則查詢會返回一個錯誤。

          clip_image014

          EMP表與DEPT表中的DEPTNO字段名稱相同,且類型相同。

           

          3.   使用Using子句的連接

          如上面(2)的例子,如果兩個字段的名稱相同,但類型不同就會出現(xiàn)錯誤。此時可以在語句后邊加上USING(字段名)子句,來設(shè)置用于等值連接,只要值可比,類型不同也可以。

           

          4.   完全外連接或者左右外連接

          左外連接:

          顯示左邊表中所有行,即使在右邊的表中沒有可對應(yīng)的列值。這與8i中的右外連接是相同的,但這個更直觀的指向左邊,而不像8i中那樣反著。

          clip_image016

           

          右外連接:

          顯示右邊表中所有行,即使在左邊的表中沒有可對應(yīng)的列值。這與8i中的左外連接是相同的,但這個更直觀的指向右邊,而不像8i中那樣反著。

          clip_image018

           

          完全外連接:顯示連接表中的所有記錄,包括不存在對應(yīng)記錄的記錄。全外連接是對兩個表中的記錄都不加限制。

          clip_image020

          5.   搞不懂里邊的條件語句還有什么用。不加上就語法錯誤!(外連接中可以使用任意的連接條件

           

          子查詢:

          之前我們學(xué)習(xí)的都是直接使用某一固定或函數(shù)返回值做為限定條件,但這能滿足我們的操作嗎?即使有連接這樣看起來十分強(qiáng)大的功能。當(dāng)然不能,子查詢解決了更多的問題!

           

          SELECT select_list

          FROM   table

          WHERE  expr  operator

          (SELECT select_list FROM  table);

           

          1、子查詢在主查詢前執(zhí)行一次

          2、主查詢使用子查詢的結(jié)果

          3、子查詢語句中不能使用外部的別名

           

          使用子查詢的注意事項:

          1、子查詢要用括號括起來

          2、將子查詢放在比較運(yùn)算符的右邊(增強(qiáng)可讀性)

          3、只有在執(zhí)行Top-N分析時,子查詢中才需要使用Order by子句

          4、在Oracle8i之前的版本中,子查詢不能包含Order by子句

          5、對單行子查詢使用單行運(yùn)算符

          6、對多行子查詢使用多行運(yùn)算符

           

          子查詢的種類:

          1.        單行單列子查詢:只包含一個字段的查詢,返回的查詢結(jié)果也只包含一行數(shù)據(jù)

          2.        多行單列子查詢:只包含了一個字段,但返回的查詢結(jié)果可能多行或者零行

          3.        多列子查詢:包含多個字段的返回,查詢結(jié)構(gòu)可能是單行或者多行。

           

          單行子查詢所使用的比較運(yùn)算符:

          Operator

          Meaning

          =

          Equal to

          > 

          Greater than

          >=

          Greater than or equal to

          < 

          Less than

          <=

          Less than or equal to

          <> 

          Not equal to

          例,查詢薪金小于平均薪金的員工,對他們加強(qiáng)培訓(xùn)提高工作技能,漲工資:

          clip_image022

           

          多行子查詢所使用的比較運(yùn)算符:

          Operator

          Meaning

          IN

          IN列表中任意一個值相等

          ANY

          與子查詢返回的任意一個值比較,ANY通常與大小寫符號搭配使用,不單獨(dú)使用。可以是<ANY >ANY

          <ANY 小于子查詢數(shù)據(jù)中的最大值

          >ANY 大于子查詢數(shù)據(jù)中的最小值

          ALL

          與子查詢返回的每一個值比較,ALL通常與大小寫符號搭配使用,不單獨(dú)使用。可以是<ALL >ALL

          >ALL 指大于子查詢數(shù)據(jù)中的最大值

          <ALL 指小于子查詢數(shù)據(jù)中的最小值

           

          例,查詢出比平均工資高的員工,給他們升職和更多成長的機(jī)會:

          clip_image024

           

          以上都只是簡單的舉了幾個例子,函數(shù)和語句等組合應(yīng)用,會讓你感到吃驚,功能驚人。當(dāng)然,我也這只是一個程序員對數(shù)據(jù)庫的了解。DBA玩的就深一些,那里有更強(qiáng)大的功能,主要是對表優(yōu)化的。先不深入了,這些夠用了,明天講解Oracle觸發(fā)器、存儲過程、視圖等!

           

          下面例出三個今日老馮給我們做的練習(xí):
          1.
          查詢各個管理者的編號及其手下員工的最低工資,其中最低工資不能低于1200,沒有管理者的員工不計算在內(nèi)。

          clip_image026

           

          2. 查詢所有部門的名稱,loc,員工數(shù)量和工資平均值。

          clip_image028

           

          3. 查詢在loc為紐約的部門工作的員工的員工號,ename,deptno,job(使用連接查詢,子查詢兩種查詢方式)

          clip_image030

           

           

          OK,歡迎明天的到來,數(shù)據(jù)庫這塊算是完了!

           

          加油!


          評論

          # re: 2009-12-07傳智播客 數(shù)據(jù)庫&mdash;&mdash;orcale表連接和子查詢  回復(fù)  更多評論   

          2009-12-14 16:21 by yjie
          請問一下,我在orcale 中兩張表join 查詢,只有用 left join 才有結(jié)果返回,但是只返回第一張表的數(shù)據(jù),換其他join 都查不出數(shù)據(jù),是怎么回事啊?
          謝謝幫助!

          # re: 2009-12-07傳智播客 數(shù)據(jù)庫&mdash;&mdash;orcale表連接和子查詢  回復(fù)  更多評論   

          2009-12-23 00:02 by 長城
          @yjie
          不好意思兄弟,我才看到!
          你使用left outer join to 能看到數(shù)據(jù),但使用right outer join to和outer outer join to 卻看不到數(shù)據(jù),會不會是你的條件指定的問題?或是指定的字段問題?
          我不是Oracle專家,但希望能幫助你解決問題。

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 阿拉善盟| 英超| 宁安市| 崇文区| 托克逊县| 麟游县| 闵行区| 新兴县| 阳曲县| 新沂市| 诸暨市| 咸丰县| 红原县| 石河子市| 阿拉善右旗| 高尔夫| 宜春市| 泗洪县| 长治县| 英吉沙县| 玛曲县| 札达县| 老河口市| 鱼台县| 东台市| 双江| 富顺县| 新密市| 巴林左旗| 若尔盖县| 南康市| 从江县| 高邮市| 德格县| 伊金霍洛旗| 福贡县| 武清区| 瑞金市| 龙州县| 鲁甸县| 威信县|