如何在SelectById存储过程中使用内连接与子查询实现多表关联查询
问题根因
你当前代码的核心问题是把Images表写在了EXISTS子查询内部,子查询的表作用域仅在子查询内生效,外层SELECT语句根本访问不到别名i对应的字段,直接写i.Url这类字段会触发「对象名i无效」的报错。另外你定义了入参@Id却没有在查询中做过滤,会返回整张FriendsV2表的所有数据,不符合按ID单查的需求。
修正后的存储过程
ALTER proc [dbo].[Friends_SelectByIdV3] @Id int as /* ------ Test Code -------- DECLARE @id int = 1; EXECUTE [dbo].[Friends_SelectByIdV3] @id */ Begin SELECT f.Id, i.Url, i.Id AS PrimaryImageId, i.TypeId AS PrimaryImageTypeId, f.Title, f.Bio, f.Summary, f.Headline, f.Slug, f.StatusId, f.DateModified, f.DateCreated, f.UserId, Skills = ( SELECT s.id as skillId, s.Name as name FROM dbo.Skills as s INNER JOIN dbo.FriendSkills as fs ON fs.SkillId = s.Id WHERE fs.FriendId = f.Id FOR JSON AUTO ) FROM dbo.FriendsV2 as f -- 业务要求好友必须有主图就把LEFT JOIN换成INNER JOIN LEFT JOIN dbo.Images as i ON i.Id = f.PrimaryImageId WHERE f.Id = @Id ORDER BY f.Id End
修改说明
- 移除了无意义的
EXISTS子查询,直接在主查询层通过外键PrimaryImageId关联Images表,外层可以正常读取图片表的所有需要字段 - 补全了入参过滤条件
WHERE f.Id = @Id,符合存储过程按ID单条查询的设计目的 - 给Images表的Id、TypeId字段加了别名,避免和好友表的Id字段重名,防止后续程序映射字段时出现取值错误
- 关联方式按需选择:如果允许查询没有绑定主图的好友数据用
LEFT JOIN,如果要求好友必须绑定有效主图才返回,替换为INNER JOIN即可,逻辑和你原来写的EXISTS判断完全一致,同时支持取图片字段
内容的提问来源于stack exchange,提问作者Victor Vuong
相关产品推荐
相关产品推荐

