PL/SQL中关联查询Owner与Owned表,如何避免返回冗余数据?
解决查询冗余数据及游标错误问题
一、先修正游标中的语法错误
原游标存在多处问题,先逐一修正:
- 移除游标定义中的
INTO子句:游标定义仅需声明查询语句,INTO是在获取游标数据时使用的。 - 修正连接条件:
- owner表没有
aid字段,owned的外键aid关联的是owner的id,所以连接条件应为owned.aid = owner.id - 游标参数是
OwnerID,过滤条件要对应写成owner.id = OwnerID
- owner表没有
- 统一字段拼写:
resgisterCode和registerCode拼写不一致,需和表结构中的字段名统一(表结构里是resgisterCode,查询里要保持一致)
修正后的游标定义:
Cursor get_ownerId_registerCode(OwnerID owner.id%type) is select owner.name, owned.resgisterCode from owner join owned on owned.aid = owner.id where owner.id = OwnerID Order By owned.resgisterCode desc;
二、解决冗余数据问题
冗余数据通常由两种情况导致,对应不同解决方案:
情况1:连接条件错误导致笛卡尔积
如果原查询因为连接条件写错(比如未正确关联两张表),会产生大量冗余的笛卡尔积数据。上面修正后的连接条件已经避免了这种情况,确保只有关联的owner和owned记录被匹配。
情况2:一个owner对应多条owned记录,需去重
如果一个owner确实拥有多个resgisterCode,但你只需要唯一的resgisterCode列表,或单条聚合值,可按需求处理:
- 获取去重的resgisterCode:
Cursor get_ownerId_registerCode(OwnerID owner.id%type) is select distinct owner.name, owned.resgisterCode from owner join owned on owned.aid = owner.id where owner.id = OwnerID Order By owned.resgisterCode desc; - 获取每个owner的最大resgisterCode(如果只需要一个聚合值):
Cursor get_ownerId_registerCode(OwnerID owner.id%type) is select owner.name, max(owned.resgisterCode) as resgisterCode from owner join owned on owned.aid = owner.id where owner.id = OwnerID group by owner.name Order By resgisterCode desc;
三、补充表结构修正建议
检查owned表的外键定义,原语句中foreign key (restaurantId) references restaurant(restaunrantId)存在拼写错误(restaunrantId应为restaurantId),建议修正表结构避免后续问题:
alter table owned drop constraint [原外键名称]; alter table owned add constraint fk_owned_restaurant foreign key (restaurantId) references restaurant(restaurantId);
内容的提问来源于stack exchange,提问作者小熊呆呆Kumaa
相关产品推荐
相关产品推荐

