调整SQL逻辑满足关联查询需求
表结构与数据
表A(主键为id)
表B(主键为rl_id)
| rl_id | rl_nm | o_id | o_nm |
|---|
| 4 | a | 0 | dev |
| 5 | b | 0 | subp |
| 6 | c | 52 | subp |
表C
初始数据(场景一)
场景二数据
现有SQL
select B.rl_id,C.rl_nm,B.rl_nm,B.o_id,C.c_id
from A
inner join B on A.rl_id=B.rl_id
inner join C
on C.rl_nm=B.o_nm and
A.rl_id=case when C.c_id=B.o_id
then B.rl_id
else (case when B.o_id=0 then B.rl_id)
end
group by B.rl_id;
需求规则
- 当表C的
c_id与表B的o_id匹配,且表C的rl_nm与表B的o_nm匹配时,返回该表B记录的rl_id(例:c_id=52匹配时,返回rl_id=6); - 若无上述匹配,则根据表C的
rl_nm匹配表B的对应行,返回其rl_id。
预期输出
场景一(表C初始数据)
| B.rl_id | C.rl_nm | B.rl_nm | B.o_id | C.c_id |
|---|
| 4 | dev | dev | 61 | 0 |
| 6 | subp | subp | 52 | 52 |
场景二(表C数据为c_id=304对应rl_nm=subp和dev)
| B.rl_id | C.rl_nm | B.rl_nm | B.o_id | C.c_id |
|---|
| 4 | dev | dev | 304 | 0 |
| 5 | subp | subp | 304 | 0 |
调整后的SQL及逻辑说明
SELECT
B.rl_id,
C.rl_nm,
B.rl_nm,
CASE
WHEN C.c_id = B.o_id THEN B.o_id
ELSE C.c_id
END AS B_o_id,
CASE
WHEN C.c_id = B.o_id THEN C.c_id
ELSE 0
END AS C_c_id
FROM
A
INNER JOIN B ON A.rl_id = B.rl_id
LEFT JOIN C ON C.rl_nm = B.o_nm
WHERE
-- 优先匹配规则1的记录:c_id与o_id、rl_nm与o_nm同时匹配
(C.c_id = B.o_id AND C.rl_nm = B.o_nm)
-- 无规则1匹配时,取仅rl_nm匹配的记录
OR (NOT EXISTS (
SELECT 1
FROM C C2
WHERE C2.c_id = B.o_id AND C2.rl_nm = B.o_nm
))
GROUP BY
B.rl_id, C.rl_nm, B.rl_nm, C.c_id, B.o_id;
核心调整点
- 改用
LEFT JOIN关联表C,避免因内联过滤掉符合规则2的记录; - 通过
NOT EXISTS判断是否存在规则1的匹配,确保规则2仅在无规则1匹配时生效; - 用
CASE语句格式化输出字段,完全贴合预期的B.o_id和C.c_id展示逻辑; - 补充完整
GROUP BY字段,避免因分组字段缺失导致的语法或数据异常。
内容的提问来源于stack exchange,提问作者Gogetit