多次连接同一张表出现重复行,如何让查询返回唯一结果?
解决同表多连接导致的查询结果重复问题
你的查询返回重复行,核心原因是三次对cat_servicios_categorias_subcategorias_familias表的JOIN操作:若该表中对应categoria_id/subcategory_id/family_id的记录不唯一,或者关联链路中存在重复数据,就会产生笛卡尔积,导致结果行数翻倍。
下面是两种可行的解决办法:
方法一:直接去重(适用于关联表无重复匹配的情况)
如果cat_servicios_categorias_subcategorias_familias表中每个categoria_familia_id对应唯一记录,重复只是因为关联链路中存在重复行,直接在SELECT后加DISTINCT即可:
SELECT DISTINCT rssp.sucursa_serviciol_id, rssp.servicio_id, rssp.sucursal_id, s.clave_interna, s.nombre, cscs.nombre as nombre_categoria, cscs2.nombre as nombre_subcategoria, cscs3.nombre as nombre_familia FROM rel_sucursales_servicios_paquetes AS rssp JOIN servicios AS s ON rssp.servicio_id = s.servicio_id JOIN cat_servicios_categorias_subcategorias_familias cscs ON cscs.categoria_familia_id = s.categoria_id JOIN cat_servicios_categorias_subcategorias_familias cscs2 ON cscs2.categoria_familia_id = s.subcategoria_id JOIN cat_servicios_categorias_subcategorias_familias cscs3 ON cscs3.categoria_familia_id = s.familia_id
方法二:确保每个ID只匹配唯一记录(适用于关联表存在多匹配的情况)
如果cat_servicios_categorias_subcategorias_familias表中同一个categoria_familia_id对应多条记录,需要通过子查询限定只取一条:
SELECT rssp.sucursa_serviciol_id, rssp.servicio_id, rssp.sucursal_id, s.clave_interna, s.nombre, (SELECT nombre FROM cat_servicios_categorias_subcategorias_familias WHERE categoria_familia_id = s.categoria_id LIMIT 1) as nombre_categoria, (SELECT nombre FROM cat_servicios_categorias_subcategorias_familias WHERE categoria_familia_id = s.subcategoria_id LIMIT 1) as nombre_subcategoria, (SELECT nombre FROM cat_servicios_categorias_subcategorias_familias WHERE categoria_familia_id = s.familia_id LIMIT 1) as nombre_familia FROM rel_sucursales_servicios_paquetes AS rssp JOIN servicios AS s ON rssp.servicio_id = s.servicio_id
也可以用聚合函数(比如MAX())获取唯一值,避免LIMIT带来的不确定性:
SELECT rssp.sucursa_serviciol_id, rssp.servicio_id, rssp.sucursal_id, s.clave_interna, s.nombre, MAX(cscs.nombre) as nombre_categoria, MAX(cscs2.nombre) as nombre_subcategoria, MAX(cscs3.nombre) as nombre_familia FROM rel_sucursales_servicios_paquetes AS rssp JOIN servicios AS s ON rssp.servicio_id = s.servicio_id LEFT JOIN cat_servicios_categorias_subcategorias_familias cscs ON cscs.categoria_familia_id = s.categoria_id LEFT JOIN cat_servicios_categorias_subcategorias_familias cscs2 ON cscs2.categoria_familia_id = s.subcategoria_id LEFT JOIN cat_servicios_categorias_subcategorias_familias cscs3 ON cscs3.categoria_familia_id = s.familia_id GROUP BY rssp.sucursa_serviciol_id, rssp.servicio_id, rssp.sucursal_id, s.clave_interna, s.nombre
补充说明
重复行的本质是多表JOIN时的笛卡尔积:假设s.categoria_id对应2条记录,s.subcategory_id对应3条,s.family_id对应1条,最终结果行数就是原数据行数 × 2 × 3 × 1,自然会出现重复。上述方法从去重或限定匹配数量两个角度解决了这个问题。
内容的提问来源于stack exchange,提问作者NOE RIVERA LUGO
相关产品推荐
相关产品推荐

