项目中使用的是sql server数据库,有一个业务是要查询能满足维修多个项目的维修店有哪些,开始用intersect来做交集查询的,但由于查询效率低,改用了group by和having的方式来做查询,提高查询效率。
数据库表的关系是多对多关系,表关系如下:
维修店 maintaince表:
id | name |
---|---|
1 | 维修店1 |
2 | 维修店2 |
3 | 维修店3 |
项目 item表:
id | name |
---|---|
1 | 小保养 |
2 | 换机油 |
3 | 换刹车油 |
维修店支持维修项目的关系 support表:
id | maintainceId | itemId |
---|---|---|
1 | 1 | 2 |
2 | 2 | 1 |
3 | 1 | 1 |
4 | 3 | 3 |
5 | 2 | 3 |
6 | 1 | 3 |
比如要查询:能同时做小保养和换刹车油项目的维修店有哪些?
最开始使用的intersect查询方法:
select m.name from maintaince m,item i,support s where s.maintainceId = m.id and s.itemId = i.id and i.name = '小保养'
intersect
select m.name from maintaince m,item i,support s where s.maintainceId = m.id and s.itemId = i.id and i.name = '换刹车油';
先查找出能做小保养的维修店,然后查找出能做换刹车油的维修店,求得他们的交集,就是既能做小保养又能做换刹车油项目的维修店了。
但是实际项目中,可能有时候查询了能同时做几十个项目的维修店,此时在测试过程中发现查询效率就很低了。因此做了一些改进。
采用group by和having的方式来做查询:
select m.name from maintaince m,item i,support s where s.maintainceId = m.id and s.itemId = i.id and i.name = '小保养' or id.name = '换刹车油'
group by m.id having count(1) = 2;
此查询方法是先查找出所有能同时做小保养和换刹车油的维修店,然后依据维修店的id来做分组,再通过having设置条件,此处是2个条件,所以是筛选出此维修店数据等于2的,即是既能做小保养又能做换刹车油项目的维修店了。