多表聯接查詢

--在Pubs數據庫中,完成以下查詢
use pubs
--使用內聯接查詢出authors和publishers表中位於同一個城市的作者和出版社信息
select au_fname+'·'+au_lname as 作者,pub_name as 出版社
from authors inner join publishers
on authors.city=publishers.city
--查詢出作者號以1~5開頭的所有作者,並使用右外聯接在查詢的結果集中列出和作者
--在同一個城市的出版社名
select au_fname+'·'+au_lname as 作者,pub_name as 出版社
from authors right outer join  publishers
on authors.au_id like '[1-5]%'
where authors.city=publishers.city

--使用自聯接查找居住在 Oakland 相同郵碼區域中的作者。
select distinct a.au_fname+'·'+a.au_lname as 作者,a.au_id,a.zip
from authors a inner join authors b
on a.zip = b.zip
where a.city='Oakland' and a.au_fname <> b.au_fname

--P26《學習手冊》上機試驗的所有題目
select ascii('sql')
--結果:115

select char(66)
--結果:B

select charindex('E','HELLO')
--結果:2

select left('RICHARD',4)
--結果:RICH

select len('RICHARD')
--結果:7

select lower('RICHARD')
--結果:richard

select 'SQL'+ltrim('RICHARD')
--結果:SQLRICHARD

select reverse('ACTION')
--結果:NOITCA

select right('RICHARD',4)
--結果:HARD

select rtrim('RICHARD   ')+'SQL'
--結果:RICHARDSQL

select patindex('%BOX%','ACTIONBOX')
--結果:7

select 'RICHARD'+space(2)+'HELL'
--結果:RICHARD  HELL

select stuff('Weather',2,2,'I')
--結果:WIther

select substring('Weather',2,2)
--結果:ea

select upper('Richard')
--結果:RICHARD

select dateadd(dd,10,getdate())
--結果:2005-10-26 16:04:58.030

select datediff(dy,getdate(),'2005-01-01')
--結果:-288

select datepart(dw,'2004-10-01')
--結果:6

select datename(dw,'2004-10-01')
--結果:星期五

--第七講 多表查詢上機實驗
use recruitment
--- 需要得到年齡在35歲到40歲之間的外部候選人的信息
select * from ExternalCandidate
where datediff(yy,dbirthdate,getdate()) between 35 and 40

--- 需要在當前日期之後的10天在報紙上登載一則廣告,系統需要計算出日期並顯示
select distinct getdate() as today,dateadd(day,10,getdate()) as '10 days from today'
from newsad

--- 統計外部候選人接受測試和麪試日期的間隔的時間平均值
select avg(datediff(day,dtestdate,dinterviewdate)) as 測試面試日期間隔平均天數
from externalcandidate

--- 需要獲取外部候選人的姓名和他們申請的職位
select externalcandidate.vcandidatename as 姓名,
       position.vdescription as 申請職位
from externalcandidate left join position
on externalcandidate.cpositioncode=position.cpositioncode

--- 需要獲得在2001年應聘的外部候選人的名字,及推薦他們的招聘機構名
select externalcandidate.vcandidatename as 名字,
       recruitmentagencies.cname as 推薦他們的招聘機構名
from externalcandidate left join recruitmentagencies
on externalcandidate.cagencycode=recruitmentagencies.cagencycode
where year(externalcandidate.ddateofapplication)=2001

--- 需要獲取外部候選人的姓名以及他們的參照的招聘的廣告所屬的報紙名
select externalcandidate.vcandidatename as 姓名,
       newspaper.cnewspapername as 參照招聘廣告所屬報紙
from externalcandidate,newsad,newspaper
where externalcandidate.cnewsadno=newsad.cnewsadno and
      newsad.cnewspapercode=newspaper.cnewspapercode

--- 需要獲取大學名稱、報紙名稱以及它們地址的列表
select college.cCollegeName as 大學名稱,college.vcollegeaddress 學校地址,
       newspaper.cnewspapername as 報紙名稱,newspaper.vhoaddress as 報社地址
from college,newspaper

--問題:這兩張表之間沒有聯繫,那麼應選用何種聯接?否則這裏面有太多冗餘數據
--     是否爲同一所城市裏有哪些大學和哪些報紙?
select college.cCollegeName as 大學名稱,college.vcollegeaddress 學校地址,
       newspaper.cnewspapername as 報紙名稱,newspaper.vhoaddress as 報社地址
from college,newspaper
where college.ccity=newspaper.ccity
--因爲大學所在城市的值爲某某,而報紙所在城市的值爲某某市,因此按此不能正確查出結果
--採用以下辦法可以解決
select college.cCollegeName as 大學名稱,college.vcollegeaddress 學校地址,
       newspaper.cnewspapername as 報紙名稱,newspaper.vhoaddress as 報社地址
from college,newspaper
where left(ltrim(college.ccity),2)=left(ltrim(newspaper.ccity),2)
--還是顯示出大學表裏符合條件的記錄與報紙表裏符合條件的記錄之積,內聯接結果一樣


--第七講 多表查詢作業
--P26《學習手冊》上機作業的所有題目
use GlobalToyz
--按指定格式(詳見學習手冊P27)顯示所有運貨的報表(天數=實際到達日期-運貨日期)
select corderno as 定單號, dshipmentdate as 運貨日期,
       dactualdeliverydate as 實際到達日期,
       datediff(day,dshipmentdate,dactualdeliverydate) as 運送天數
from shipment

--小結:兩日期之差運算爲第二個日期參數-第一個日期參數

--按指定格式(詳見學習手冊P27)顯示所有的訂單
select cOrderNo as 定單號,cShopperId as 購物者號,dOrderDate as '訂單日期(號)',
       datename(dw,dorderdate)星期幾
from orders

--小結:求星期幾,日期元素只能用DW,而不能用WK,WK求得是在一年中的第幾周,而列別名如果有
--      特殊字符需要引號引起來

--顯示所有玩具名和所屬的種類名
select toys.vToyName as 玩具名,Category.cCategory as 種類名
from category join toys
on toys.cCategoryId = Category.cCategoryId

--小結:交叉聯接不能使用條件,而內聯接和右外聯接在此效果相同,
--     左外聯接和全外聯接效果相同,但多出九條玩具名爲空的記錄,
--     因爲左外聯接時將顯示所有左表中即種類表中的記錄,即使沒有該玩具屬於該種類,
--     此時玩具名爲NULL值
--     JOIN前不加關鍵字時默認爲內聯接
--     用join聯接表名時,後面條件語句只能先跟on關鍵字,不能直接用where
--按指定格式(詳見學習手冊P27)顯示所有玩具的名稱、商標和種類
select toys.vtoyname as 玩具名,ToyBrand.cBrandName as 商標名,
       Category.ccategory as 類別名
from toys,ToyBrand,Category
where toys.cBrandId=ToyBrand.cBrandId and toys.cCategoryId=Category.cCategoryId

--問題:如果用逗號聯繫多張表,之間採用的是什麼聯接方式?表與表之間的前後順序影不影響結果?

--按指定格式(詳見學習手冊P28)顯示所有玩具的訂貨號、玩具ID和玩具使用的禮品包裝說明
select orderdetail.corderno as 定單號,orderdetail.ctoyid as 玩具號,
       wrapper.vdescription as 包裝信息
from orderdetail left join wrapper
on orderdetail.cwrapperid=wrapper.cwrapperid

select orderdetail.corderno as 定單號,orderdetail.ctoyid as 玩具號,
       wrapper.vdescription as 包裝信息
from toys,orderdetail,wrapper
where toys.ctoyid=orderdetail.ctoyid and orderdetail.cwrapperid=wrapper.cwrapperid

--小結:外連接的關鍵字outer可以省略不寫
--問題:採用以上方式查出的結果好象未能滿足需求,沒有顯示所有的玩具,如果用三張表,即
--      加入toys表後,加上一個toys.ctoyid=orderdetail.ctoyid後也不能列出所有玩具。

--按指定格式(詳見學習手冊P28)顯示所有購物者名,及他們所購買的訂單信息(無論購物者是否有訂單)
select shopper.vfirstname as 購物者名,orders.corderno as 定單號,
       orders.dorderdate as 定單時間,orders.mtotalcost as 定單金額
from shopper left join orders
on shopper.cshopperid=orders.cshopperid


--按指定格式(詳見學習手冊P28)顯示訂單號碼、訂單日期和每個訂單所在的季節
select cOrderNo as 定單號,dOrderDate as 定單日期,datename(qq,dOrderDate) as 季節
from orders

--問題:如果要顯示季節,是否需要用到分支選擇語句?

--按指定格式(詳見學習手冊P28)顯示所有購物者ID、名字、電話和相應訂單的接受者
select shopper.cshopperid as 購物者號,shopper.vfirstname as 名字,
       shopper.cphone as 電話,recipient.vfirstname as 接受者名,recipient.cphone as 電話
from shopper,orders,recipient
where shopper.cshopperid = orders.cshopperid and orders.corderno = recipient.corderno

--小結:如果表與表之間聯接沒用JOIN,則條件語句關鍵字不能用ON,只能用WHERE

--按指定格式(詳見學習手冊P28)顯示所有購物者和接受者的名字、地址
select shopper.vfirstname as 購物者名字,shopper.vaddress as 購物者地址,
       recipient.vfirstname as 接受者名字,recipient.vaddress as 接受者地址
from shopper,orders,recipient
where shopper.cshopperid=orders.cshopperid and orders.corderno=recipient.corderno

--顯示所有玩具名及該玩具的銷售數量
select toys.vtoyname as 玩具名,orderdetail.siqty as 銷售數量
from toys left join orderdetail
on toys.ctoyid=orderdetail.ctoyid

--顯示在2001年5月消費金額最高的前3名購物者名及消費金額
select top 3 shopper.vfirstname as 購物者名,sum(orders.mtotalcost) as 消費金額
from shopper left join orders
on year(orders.dorderdate)=2001 and month(orders.dorderdate)=5
   and shopper.cshopperid=orders.cshopperid
group by shopper.vfirstname,orders.cshopperid
order by sum(orders.mtotalcost) desc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章