如何用单SQL查询更新关联表外键以实现级联下拉功能
嘿,这个级联下拉对应的外键赋值问题我帮你捋清楚啦!
首先咱们先明确你要的关联逻辑:
- Surgery表的"Abdominal Surgery"对应TypeOfSurgery表的"Appendectomy"和"Caesarian Section"
- "Appendectomy"对应Procedure表的"procedure A"
- "Caesarian Section"对应Procedure表的"procedure B"和"Procedure C"
假设三个关联表的基础结构是:
Surgery:SurgeryId(主键),SurgeryNameTypeOfSurgery:TypeOfSurgeryId(主键),SurgeryId(外键),TypeNameProcedure:ProcedureId(主键),TypeOfSurgeryId(外键),ProcedureName
下面用**单个SQL语句(带CTE关联)**就能批量给现有条目分配对应外键ID,完美匹配你的下拉联动逻辑:
WITH SurgeryMap AS ( -- 先获取手术大类的ID与名称映射 SELECT SurgeryId, SurgeryName FROM Surgery ), TypeSurgeryMap AS ( -- 建立手术子类型与对应大类的ID关联 SELECT tos.TypeOfSurgeryId, tos.TypeName, sm.SurgeryId AS TargetSurgeryId FROM TypeOfSurgery tos JOIN SurgeryMap sm ON CASE WHEN tos.TypeName IN ('Appendectomy', 'Caesarian Section') THEN sm.SurgeryName = 'Abdominal Surgery' END ), ProcedureMap AS ( -- 建立操作步骤与对应手术子类型的ID关联 SELECT p.ProcedureId, p.ProcedureName, tsm.TypeOfSurgeryId AS TargetTypeId FROM Procedure p JOIN TypeSurgeryMap tsm ON CASE WHEN p.ProcedureName = 'procedure A' THEN tsm.TypeName = 'Appendectomy' WHEN p.ProcedureName IN ('procedure B', 'Procedure C') THEN tsm.TypeName = 'Caesarian Section' END ) -- 第一步:更新TypeOfSurgery的外键SurgeryId UPDATE TypeOfSurgery SET SurgeryId = tsm.TargetSurgeryId FROM TypeOfSurgery tos JOIN TypeSurgeryMap tsm ON tos.TypeOfSurgeryId = tsm.TypeOfSurgeryId; -- 第二步:更新Procedure的外键TypeOfSurgeryId UPDATE Procedure SET TypeOfSurgeryId = pm.TargetTypeId FROM Procedure p JOIN ProcedureMap pm ON p.ProcedureId = pm.ProcedureId;
关键细节说明:
- 验证先行:执行更新前,建议先跑下面的查询确认关联是否正确,避免误更新:
-- 验证手术子类型与大类的关联 SELECT tos.TypeName, sm.SurgeryName, sm.SurgeryId FROM TypeOfSurgery tos JOIN Surgery sm ON CASE WHEN tos.TypeName IN ('Appendectomy', 'Caesarian Section') THEN sm.SurgeryName = 'Abdominal Surgery' END; -- 验证操作步骤与手术子类型的关联 SELECT p.ProcedureName, tos.TypeName, tos.TypeOfSurgeryId FROM Procedure p JOIN TypeOfSurgery tos ON CASE WHEN p.ProcedureName = 'procedure A' THEN tos.TypeName = 'Appendectomy' WHEN p.ProcedureName IN ('procedure B', 'Procedure C') THEN tos.TypeName = 'Caesarian Section' END;
- 大小写兼容:如果你的数据存在大小写不一致的情况,可以用
LOWER()统一处理,比如LOWER(tos.TypeName) = LOWER('Appendectomy') - 数据库兼容:这个语法支持SQL Server、PostgreSQL、MySQL 8+,如果是老版本MySQL,可以把CTE换成子查询写法,逻辑是一样的。
内容的提问来源于stack exchange,提问作者eligible_net
相关产品推荐
相关产品推荐

