1. 程式人生 > >Oracle-day02 中

Oracle-day02 中

Oracle-day02 中

二、連接查詢
(一)多表內連接查詢
(1)需求:查詢顯示業主編號,業主名稱,業主類型名稱,如下圖:
技術分享圖片
查詢語句:

select o.id 業主編號,o.name 業主名稱,ot.name 業主類型
from T_OWNERS o,T_OWNERTYPE ot
where o.ownertypeid=ot.id

(2)需求:查詢顯示業主編號,業主名稱、地址和業主類型,如下圖
技術分享圖片

分析:此查詢需要三表關聯查詢。分別是業主表,業主分類表和地址表
語句:

select o.id 業主編號,o.name 業主名稱,ad.name 地址,
ot.name 業主類型
from T_OWNERS o,T_OWNERTYPE ot,T_ADDRESS ad
where o.ownertypeid=ot.id and o.addressid=ad.id

(3)需求:查詢顯示業主編號、業主名稱、地址、所屬區域、業主分類,如下圖:
技術分享圖片
分析:這裏需要四個表關聯查詢,比上邊多了一個區域表(T_AREA)
查詢語句:

select o.id 業主編號,o.name 業主名稱,ar.name 區域, ad.name 地
址, ot.name 業主類型
from T_OWNERS o ,T_OWNERTYPE ot,T_ADDRESS ad,T_AREA ar
where o.ownertypeid=ot.id and o.addressid=ad.id
ad.areaid=ar.id
and

(4)需求:查詢顯示業主編號、業主名稱、地址、所屬區域、收費員、業主分類,如下圖:

技術分享圖片
分析:此查詢比上邊又多了一個表 T_OPERATOR
語句:

select ow.id 業主編號,ow.name 業主名稱,ad.name 地址,
ar.name 所屬區域,op.name 收費員, ot.name 業主類型
from T_OWNERS ow,T_OWNERTYPE ot,T_ADDRESS ad ,
T_AREA ar,T_OPERATOR op
where ow.ownertypeid=ot.id and ow.addressid=ad.id
and ad.areaid=ar.id and ad.operatorid=op.id

(二)左外連接查詢
需求:查詢業主的賬務記錄,顯示業主編號、名稱、年、月、金額。如果此業主

沒有賬務記錄也要列出姓名。
技術分享圖片

分析:我們要查詢這個結果,需要用到 T_OWNERS(業主表) ,T_ACCOUNT
(臺賬表) 按照查詢結果,業主表為左表、賬務表為右表。
按照 SQL1999 標準的語法,查詢語句如下:

SELECT ow.id,ow.name,ac.year ,ac.month,ac.money
FROM T_OWNERS ow left join T_ACCOUNT ac
on ow.id=ac.owneruuid

按照 ORACLE 提供的語法,就很簡單了:

SELECT ow.id,ow.name,ac.year ,ac.month,ac.money FROM
T_OWNERS ow,T_ACCOUNT ac
WHERE ow.id=ac.owneruuid(+)

如果是左外連接,就在右表所在的條件一端填上(+)
(三)右外連接查詢
需求:查詢業主的賬務記錄,顯示業主編號、名稱、年、月、金額。如果賬務記
錄沒有對應的業主信息,也要列出記錄。如下圖:
技術分享圖片

SQL1999 標準的語句

select ow.id,ow.name,ac.year,ac.month,ac.money from
T_OWNERS ow right join T_ACCOUNT ac
on ow.id=ac.owneruuid
ORACLE 的語法
select ow.id,ow.name,ac.year,ac.month,ac.money from
T_OWNERS ow , T_ACCOUNT ac
where ow.id(+) =ac.owneruuid

三、子查詢
(一)where 子句中的子查詢

  1. 單行子查詢
    l 只返回一條記錄
    l 單行操作符
    技術分享圖片
    需求:查詢 2012 年 1 月用水量大於平均值的臺賬記錄
    語句:
select * from T_ACCOUNT
where year=‘2012‘ and month=‘01‘ and usenum>
( select avg(usenum) from T_ACCOUNT where year=‘2012‘ and

month=‘01‘ )

查詢結果:
技術分享圖片
平均值為:
技術分享圖片

  1. 多行子查詢
    l 返回了多條記錄
    l 多行操作符
    技術分享圖片
    in 運算符
    (1)需求:查詢地址編號為 1 、3、4 的業主記錄
    分析:如果我們用 or 運算符編寫,SQL 非常繁瑣,所以我們用 in 來進行查詢
    語句如下:
select * from T_OWNERS
where addressid in ( 1,3,4 )

查詢結果如下:
技術分享圖片
(2)需求:查詢地址含有“花園”的業主的信息
語句:

select * from T_OWNERS
where addressid in
( select id from t_address where name like ‘%花園%‘ )

查詢結果:
技術分享圖片
(3)需求:查詢地址不含有“花園”的業主的信息語句:

select * from T_OWNERS
where addressid not in
( select id from t_address where name like ‘%花園%‘ )

查詢結果:
技術分享圖片
(二)from 子句中的子查詢
from 子句的子查詢為多行子查詢
需求:查詢顯示業主編號,業主名稱,業主類型名稱,條件為業主類型為”居民”,
使用子查詢實現。
語句:

select * from

(select o.id 業主編號,o.name 業主名稱,ot.name 業主類型
from T_OWNERS o,T_OWNERTYPE ot
where o.ownertypeid=ot.id)
where 業主類型=‘居民‘

查詢結果如下:
技術分享圖片
(三)select 子句中的子查詢
select 子句的子查詢必須為單行子查詢
(1)需求:列出業主信息,包括 ID,名稱,所屬地址。
語句:


select id,name,
(select name from t_address where id=addressid) addressname
from t_owners

查詢結果如下:
技術分享圖片

(2)需求:列出業主信息,包括 ID,名稱,所屬地址,所屬區域。
語句:


select id,name,
( select name from t_address where id=addressid )
addressname,
( select (select name from t_area where id=areaid ) from
t_address where id=addressid )
adrename
from t_owners;

查詢結果如下:
技術分享圖片
四、分頁查詢
(一)簡單分頁
需求:分頁查詢臺賬表 T_ACCOUNT,每頁 10 條記錄
分析:我們在 ORACLE 進行分頁查詢,需要用到偽列 ROWNUM 和嵌套查詢
我們首先顯示前 10 條記錄,語句如下:


select rownum,t.* from T_ACCOUNT t where rownum<=10

顯示結果如下:
技術分享圖片

那麽我們顯示第 11 條到第 20 條的記錄呢?編寫語句:

select rownum,t.* from T_ACCOUNT t
where rownum>10 and rownum<=20

查詢結果:
嗯?怎麽沒有結果?
這是因為 rownum 是在查詢語句掃描每條記錄時產生的,所以不能使用“大於”
符號,只能使用“小於”或“小於等於” ,只用“等於”也不行。
那怎麽辦呢?我們可以使用子查詢來實現

select * from
(select rownum r,t.* from T_ACCOUNT t where rownum<=20)
where r>10

查詢結果如下:
技術分享圖片
(二)基於排序的分頁
需求:分頁查詢臺賬表 T_ACCOUNT,每頁 10 條記錄,按使用字數降序排序。
我們查詢第 2 頁數據,如果基於上邊的語句添加排序,語句如下:

select * from
(select rownum r,t.* from T_ACCOUNT t where rownum<=20 order
by usenum desc)
where r>10

查詢結果如下:
技術分享圖片
經過驗證,我們看到第 2 頁的結果應該是下列記錄
所以推斷剛才的語句是錯誤的!那為什麽是錯誤的呢?
我們可以先單獨執行嵌套查詢裏面的那句話

select rownum r,t.* from T_ACCOUNT t
where rownum<=20 order by usenum desc

你會看到查詢結果如下:

技術分享圖片
你會發現排序後的 R 是亂的。這是因為 ROWNUM 偽列的產生是在表記錄掃描
是產生的,而排序是後進行的,排序時 R 已經產生了,所以排序後 R 是亂的。
那該如何寫呢?
很簡單,我們只要再嵌套一層循環(一共三層),讓結果先排序,然後對排序後
的結果再產生 R,這樣就不會亂了。
語句如下:

select * from
(select rownum r,t.* from
(select * from T_ACCOUNT order by usenum desc) t
where rownum<=20 )
where r>10

結果如下:
技術分享圖片

Oracle-day02 中