1 背景
根据业务需要,需要使用如下的命令进行多表联查
select a.id as a_id, b.id as b_id, b.protocol as protocol, b.priority as priority
from (a, b) left join c on (a.network_id = c.network_id) where (a.id = b.acl_id
and c.network_id = 'dec4f9c4-f562-451d-8edf-fce4284b7fa1')
结果如下
+--------------------------------------+--------------------------------------+----------+----------+
| 06b93477-4ca7-41c8-86f7-0ade65e11b8c | 47844358-0828-4f8d-a9c5-0a21bb1e1e86 | udp | 50 |
| 06b93477-4ca7-41c8-86f7-0ade65e11b8c | 47844358-0828-4f8d-a9c5-0a21bb1e1e86 | udp | 50 |
| 06b93477-4ca7-41c8-86f7-0ade65e11b8c | 9da262cc-48df-4cab-9a70-10f84e190c82 | tcp | 12 |
| 06b93477-4ca7-41c8-86f7-0ade65e11b8c | 9da262cc-48df-4cab-9a70-10f84e190c82 | tcp | 12 |
| 06b93477-4ca7-41c8-86f7-0ade65e11b8c | eb5d478e-e838-4d6d-98b5-f7f49b2d2634 | ip | 17 |
| 06b93477-4ca7-41c8-86f7-0ade65e11b8c | eb5d478e-e838-4d6d-98b5-f7f49b2d2634 | ip | 17 |
+--------------------------------------+--------------------------------------+----------+----------+
发现结果很多重复项
2 解决方法
当时直接想到的是加DISTINCT进行去重,效果确实能够达到且立竿见影,除此之外,也可以在语句末尾添加group by b_id 来实现同样的效果。 但是不能只知其然,后来发现,是自己join的c表没有关联主键或者说是value唯一性的字段。 通过对该表以该字段查询后发现确实存在两行数据,换言之,如果在c表中查询该字段对应的数据后 即SELECT * FROM c WHERE c.network_id = '123456789'; 结果显示数据有n行,那么根据笛卡尔积,left join 将会产生m * n条数据,会重复n倍。
3 总结
使用多表联查时尽量关联到主键上或者具有唯一约束的字段上,或者可以习惯性的加上DISTINCT来进行查询结果的去重。
|