跟我一起學Oracle 11g【8】----SQL 基礎學習2[連接查詢]


前言

前面的查詢主要都是針對一個表而言的。但是,在我們項目現實中,有更多的是多個表聯合起來查詢。所以,若一個查詢同時涉及2個以上的表,那么我們就叫它為連接查詢。連接查詢是數據庫中最重要的查詢,主要包括等值連接查詢、自然連接查詢、非等值連接查詢,自身連接查詢、外連接查詢和復合條件查詢。

一。連接查詢

1.1等值與非等值查詢

連接查詢的where字句總用來連接2個表的條件稱為連接條件或者連接謂詞。格式如下:

[<表名>.] <列名> <比較運算符> [<表名>.] <列名>

其中比如運算符有:等於(=)、大於(>)、小於(<)、大於等於(>=)、小於等於(<=)、不等於(用!=或者用<>都可以)等。

連接條件我們還可以使用我們在上面一張提到過的 between....and的形式:

[<表名>] <列名> between [表名] <列名> and[表名] <列名>

使用“=”叫等值連接,其他則稱為非等值連接。

【例子1】查詢每個學生及其選修課的情況

我們在select字句中加上了表名,這樣是為了防止混淆。如果屬性名在參加連接的各表中是唯一的,則可以省略表名前綴。因為在我們的student表和course表均有sno,所以就不能省略咯。

我們也可以使用as 為表指定別名。

當然,我們這里使用表的別名的效果不太明顯,如果在多張表連接起來的時候,使用通俗易懂的表名對我們有很大的幫助。

如果在等值連接中,把目標列中重復的屬性列去掉則為自然連接。

【例子2】用自然連接重現例子1

因為sno在2個表都有,所以需要指定表名前綴,而其余的由於不沖突,所以可以不用。

1.2自連接

連接不僅可以再2個表中進行連接,而且還可以一個表自己和自己進行連接。

自連接主要是用來顯示上下級關系或者層次關系的,

【例子3】查詢每一門課的簡介先修課(也就是先修課的先修課)

因為早course表中,只有每門課的直接先修課,而沒有先修課的先修課。要得到這個信息,就必須先對一門課找到其先修課,在按照此先修課的課程號,查找它的先修課。

我們定義了2個表,first表和second表,

這里可能有點繞,需要好好琢磨琢磨這里。

自連接我在一個oracl數據自帶的一個例子,可能比較更好的理解。在Oracle中有一個表叫emp(conn scott/tirger),emp表里有一個列叫mgr,他是每個員工管理者的員工號,如果員工沒有管理者則mgr為空。(比如在公司里,員工都屬於某個經理,經理屬於老板,而老板上面沒有人了就為空。)

OK,那我們現在需要找出誰是誰的manger,什么意思呢?我現在要找比如blake和clark的老板是king。。

select m.ename || ' is ' || n.ename || ' Manger'
from emp m,emp n
where n.mgr=m.empno;

結果如下:

這里找出了誰是誰的manger,用的就是自連接。

1.3外連接

OK,我們現在在學生表Student中加入一條數據:

insert into student values(005,'XiaoZhang','Male',18,'IS');

然后,我們在【例子2】去查:

我們沒有找出XiaoZhang這個人。因為XiaoZhang這個人沒有選課,所以它的數據就被拋棄了。但是,我現在想要全部學生的信息,不管他有沒有選課呢?那怎么辦呢?這個時候,我們就需要使用外連接了。

外連接,分為左外連接、右外連接以及全連接

左外連接:不僅會返回連接表中滿足連接條件的所有語句,而且還會返回不滿足連接條件的連接符左邊表的其他行。(比如例子4)

右外連接:不僅會返回連接表中滿足連接條件的所有語句,而且還會返回不滿足連接條件的連接符右1邊表的其他行

全連接:列出所有表的值。

【例子4】重現【例子1】查詢每個學生及其選修課的情況

因為用的是左外連接,所以把左邊表student的值全部顯示出來,而不用管它有沒有選課。

右外連接也是一樣,語句如下:

 select student.sno,sname,ssex,sage,sdept,cno,grade 
from student righ outer join sc on(student.sno=sc.sno);

全連接語法:

select student.sno,sname,ssex,sage,sdept,cno,grade 

from student inner join sc on(student.sno=sc.sno);

另外一種寫法:

在oracle中,對左外連接和右外連接還有另外一種寫法:

左外連接是:左條件 = 右條件(+)

右外連接是:左條件(+) = 右條件

比如,我們現在的例子,我們只需要這樣也可以得到一樣的結果:

select student.sno,sname,ssex,sage,sdept,cno,grade 
from student,sc
where student.sno=sc.sno(+);

結構也是一樣的哦!。

Oracle 建議你用from語句后加Outer Join語法,而不是Oracle的Join操作符(+).而且(+)是要受下面的規則限制的,但Outer Join語法則不受。

  • 你不可以 在查詢塊中使用(+) 當它同時包含 join的from語句中
  • (+)只是在where語句中,並且只能對應一個表或視圖的一行字段
  • 如果A和B做聯接時有多個條件,那么(+)必須完善所有的匹配條件,
    如果沒有 ,oracle不會警告你~只是結果自然不同的
  • 不 可以在作出一個表外查詢 另張表內查詢的(+)聯接操作
  • 不可以用(+)外聯接到自己 當然Self Join是可以的
  • 含 (+)的Where后的注意
    OR不可用
    IN不可用
    子查詢不可用

我們這里也在舉一個oracle數據庫自帶的例子。有2個表emp表(員工表)和dept表(部門表) 每一個員工屬於不同的部門中。

左外連接:

select d.dname,e.ename
from emp e left outer join dept d on(e.deptno=d.deptno);
當然也可以這樣寫:
select d.dname,e.ename from emp e,dept d where e.deptno=d.deptno(+);

列出了所有左邊列emp的員工名字(ename)。

右外連接:

1.4復合條件連接

所謂的復合條件查詢,在where子句中可以有多個連接條件。

【例子5】查詢選修課為2號課程並且成績在90分以下的同學

select student.sno,sname,grade 
from student,sc where sc.sno=student.sno --連接謂詞,需要先對表進行連接
and sc.Cno=2 and SC.Grade<=90; ---其他的限定條件

結果如下:

二。算數運算

當我們在執行查詢的時候,我們也可以再數字列使用算術表達式(+,-,*,/)。其中,乘和除的優先級要高於加減。

【例6】為了應付上面的檢查,現在需要把分數小於80分的人,加上20分。

select sname,grade+20 from student,sc 
where student.sno=sc.sno and grade<80;

結果如下:

三。集合查詢

本來這部分應該放到下一章節里講的,可是因為嵌套查詢的內容比較多,所以就提前講的,里面的一些嵌套內容大家先了解下。

select語句的查詢結果是元組的集合,所有多個select語句的結構可以進行集合操作。

集合操作包括並操作Union、交操作Intersect、差操作except。需要特別注意的是,參加集合操作的各查詢結果的列數必須相同;對應的數據類型也必須相同。

把這些和數學上的交集、並集以及差集就很好理解了。

3.1並操作Union

也就是or操作,把符合條件的列都列出來。

【例7】查詢計算機系的學生以及年齡不大於20歲的學生

select *
from student
where sdept='CS'
Union
select *
from Student
where sage<20;

等價於:

 select * from student where sdept='CS' or sage<20;

結果如下:

使用Union將多個查詢結果合並起來,系統會自動去除重復元組,如果要保留重復元組則要用Union All操作符。

3.2交操作Interact

【例7】查詢計算機系的學生以及年齡不大於20歲的學生的交集

select *
from student
where sdept='CS'
Intersect
select *
from Student
where sage<20;

也就是等價於:

select * from student where sdept='CS' and sage<20;

結果如下:

【例8】查詢既選修課程1又選修課程2的學生。

select sno from sc where cno=1 

intersect

select sno from sc where cno=2;

也就是:

select Sno
from sc
where cno=1 and Sno in(
             select Sno
             from sc
             where cno=2); ---這個表達式會在下面一章節中介紹。

3.3差集except

【例9】查詢計算機系的學生以及年齡不大於20歲的學生的差集

select * from student where sdept='CS'
minus
select * from student where sage<20;

要記得的是不大於。等價於下面的SQL語句:

select *
from student 
where sdept='CS' and sage>20;

均可以得到下面的結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM