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;