MySQL三表内连接查询结果出现多余license_plate、Id_Code列问题
多对多关联查询冗余字段问题解决
表结构说明
当前通过三张表实现车辆与客户的多对多关系:
Car(车辆主表):以license_plate(车牌号)为主键,存储Model(车型)字段Client(客户主表):以Id_Code(身份编码)为主键,存储Name(名)、Surname(姓)、Phone(联系电话)字段Car_Client(关联中间表):通过两个外键关联主表,license_plate外键关联Car表,Id_Code外键关联Client表
三张表的结构示意:
_____________________ ___________________ ______________________ | Car | | Client | | Car_Client | |___________________| |_________________| |____________________| | license_plate (PK)| | Name | | license_plate(fk) | | Model | | Surname | | Id_Code(fk) | |___________________| | Id_Code (PK) | |____________________| | Phone | |_________________|
需求与现有问题
需要实现按客户姓名检索的功能:输入客户姓名后,返回匹配客户的个人信息,以及其名下绑定的所有车辆信息,结果无冗余列。
当前使用的查询语句如下:
SELECT * FROM Car_Client car_cli INNER JOIN Car ON ( car_cli.license_plate = car.license_plate) INNER JOIN Client ON ( car_cli.Id_Code = Client.Id_Code) WHERE Car_Client.Id_Code in (SELECT Id_Code FROM Client WHERE Name = 'emanuele');
该写法的核心问题是使用SELECT *拉取了三张表的全部字段,中间表存储的license_plate、Id_Code两个外键字段和Car、Client主表的主键字段完全重复,造成结果集出现多余列。
优化后查询写法
摒弃SELECT *的写法,显式指定需要返回的业务字段即可解决冗余问题,同时简化原有的子查询过滤逻辑,减少不必要的表扫描:
SELECT -- 客户信息字段 cli.Id_Code, cli.Name, cli.Surname, cli.Phone, -- 车辆信息字段 car.license_plate, car.Model FROM Car_Client car_cli INNER JOIN Car car ON car_cli.license_plate = car.license_plate INNER JOIN Client cli ON car_cli.Id_Code = cli.Id_Code WHERE cli.Name = 'emanuele';
优化点说明
- 显式指定返回字段是SQL编写的通用规范,除了消除重复冗余列,还能避免表结构变动时返回非预期字段,同时降低查询结果的传输开销
- 直接在Client表关联后加姓名过滤条件,替换原有的IN子查询,执行路径更短,查询效率更高
- 如果业务场景中存在同名用户,可追加
Surname、Id_Code等精准过滤条件,避免返回非目标用户的数据
内容的提问来源于stack exchange,提问作者emanuele pascale
相关产品推荐
相关产品推荐

