1. 程式人生 > >A/B表為1對多關係,要求聯合查詢B表只提取一條與A記錄關聯的記錄

A/B表為1對多關係,要求聯合查詢B表只提取一條與A記錄關聯的記錄

我現在 有主表 A  和從表B 

A表字段有:  XM nvarchar2(100), RY_ID nvarchar2(32)
B表字段有:  RY_ID nvarchar2(32),  XL  nvarchar2(50), HID NUMBER(7,0)

B的RY_ID為外來鍵關聯到A表的RY_ID,所以A/B表形成了一對多的關係。

想查詢的結果集包括A表中的記錄,同時在B表中提取第一條跟A表記錄關聯的記錄。這個語句該怎麼寫?

如:
A表  RY_ID    XM  
           1          張三
           2          李四
           3          王二麻子
     ……
     
B表  ID   RY_ID      XL      HID    XLLX(學歷型別 ,例2用到)
         1         1        大學生    1         1
         2         1        研究生    2         2
         3         1        博士        3         2
         4         2        高中        1         1
         5         2        中專        2         1
         6         3        小學        1         1     
     ……
例1:查詢結果要求為:(取每個人HID值最大的XL)
     RY_ID       XM             XL
         1          張三            博士
         2          李四            中專
         3          王二麻子    小學

select a.RY_ID,a.XM,b.XL 
 from A a 
 left join (
 SELECT * FROM B W1 WHERE NOT EXISTS(
 SELECT 1 FROM B W2 WHERE W2.RY_ID=W1.RY_ID AND W1.HID < W2.HID)
 ) b on a.RY_ID=b.RY_ID;

補充說明:

SELECT * FROM B W1 WHERE NOT EXISTS(  
 SELECT 1 FROM B W2 WHERE W2.RY_ID=W1.RY_ID AND W1.HID < W2.HID) 這裡的not exists ,以及後面的 W1.HID < W2.HID 怎麼理解呢?

先不看 exists  先看 B 表的自連線。

W1表 和 W2 表 連線的第一個條件  W2.RY_ID=W1.RY_ID  人員id 的相連 ,圖例:


然後再看 第二個條件 W1.HID < W2.HID 這裡  就很容易理解了,紅色,綠對勾 是 同時滿足 W2.RY_ID=W1.RY_ID and W1.HID < W2.HID 的記錄 ,


然後就是怎麼理解 not EXISTS  這個 結果集了


因為 查詢主語句 是 SELECT * FROM B W1   也就是W1 表  W2 表 看做 另一個表   所以說 W1 表 裡面  EXISTS  hid =1 、2 並且 ry_id=1 的記錄 ,反之  not EXISTS  剩下的 也就是 hid=3 並且ry_Id =1的記錄 也就是 需求裡面  的 每個人的 hid 最大的記錄

例2:查詢結果要求為:(取每個人HID值最大的XL(學歷),同時按XLLX(學歷型別)分開統計)
     RY_ID       XM         全日制學歷      在職學歷
       1          張三               大學生             博士
       2        李四                 中專                 NULL
       3        王二麻子         小學                 NULL

 select a.RY_ID,a.XM,C1.XL  as  全日制學歷, C2.XL as 在職學歷
 from A a 
 left join (
 SELECT * FROM B W1 WHERE W1.XLLX='1' and NOT EXISTS(
 SELECT 1 FROM B W2 WHERE W2.XLLX='1' and W2.RY_ID=W1.RY_ID AND W1.HID < W2.HID)
 ) C1 on a.RY_ID=C1.RY_ID
 left join (
 SELECT  * FROM B W1 WHERE W1.XLLX='2' and NOT EXISTS(
 SELECT 1 FROM B W2 WHERE W2.XLLX='2' and W2.RY_ID=W1.RY_ID AND W1.HID < W2.HID)
 ) C2 on a.RY_ID=C2.RY_ID;