SQL Server 2012关联查询需求:按优先级匹配LabTest数据
解决Fields与LabTest的条件关联查询问题
我来帮你搞定这个关联查询的需求!首先咱们先明确核心规则,避免走弯路:
- 优先匹配testid和labid都完全一致的
Fields和LabTest行 - 若没有上述匹配,再匹配
LabTest中testid相同且labid为null的行 - 必须保留
Fields中所有行(包括testid为null的行)
你之前的左连接只匹配了testid,所以会把所有testid相同的行都关联起来,导致testid1连出2行、testid2连出3行,总共5行,不符合优先匹配的要求。下面是调整后的SQL语句,完美满足你的需求:
SELECT f.*, lt.* FROM Fields f LEFT JOIN LabTest lt ON f.testid = lt.testid AND ( -- 优先匹配testid和labid都一致的行 lt.labid = f.labid -- 当没有labid匹配的行时,匹配testid相同且labid为null的行 OR ( lt.labid IS NULL AND NOT EXISTS ( SELECT 1 FROM LabTest lt2 WHERE lt2.testid = f.testid AND lt2.labid = f.labid ) ) )
语句逻辑拆解:
- 优先匹配分支:
lt.labid = f.labid直接匹配testid和labid都完全一致的行,比如testid1的情况,会匹配到LabTest中testid1, labid=1的那一行,不会关联labid=null的行。 - 备选匹配分支:当
NOT EXISTS判断当前Fields行的testid和labid组合在LabTest中没有匹配时,才会关联testid相同且labid为null的行,比如testid2的情况,因为LabTest里没有testid2, labid=2的行,所以会关联所有testid2且labid=null的3行。 - 保留无testid的Fields行:因为是左连接,Fields中testid为null的行不会匹配到任何LabTest行,所以会完整保留这些行,lt的字段会显示为null。
执行这个语句后,testid1会返回1行,testid2会返回3行,完全符合你的需求。
内容的提问来源于stack exchange,提问作者aggicd




