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;



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燕儿归

感谢感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值