现有两个实体类:模型(model)和模具(mould),模具:模型=n:1
表结构如下:
mould_mode_info:模型表
modelId:主键
其他基础信息略
mould_info:模具表
mouldId:主键
modelId:模具对应的模型的id
其他基础信息略
问题:要求查询出模型只有单个模具的模具编号和对应的模型编号
一开始写出的sql 语句如下:
select mi.mouldId, mi.modelId
from mould_info mi
where mi.modelId in (
select mmi.modelId
from mould_info mi
left join mould_model_info mmi on mmi.modelId = mi.modelId
group by mmi.modelId
having count(mi.mouldId) = 1)
一开始的想法是:先查询出只有单套模具的模型的id,再通过模型的id 在模具表中查找,但是这样子就会做两次的select,在explain 中其实是总共查询了三次表,两次模具表,一次模型表。
诚然,这样子可以解决问题,但是查询的次数太多,好像不太值得。
写完了sql,总觉得哪里不太对,我明明模具模型表已经连接过一次,为什么还要在查询一次呢,所需的查询结果已经在连表查询的结果中有了,是否可以通过过滤的方式,得到这些结果就好,不需要再去查询一次。
然后,我就写出了下面这样子的 sql:
select mi.mouldId as mouldId,mi.modelId
from mould_info mi
left join mould_model_info mmi on mmi.modelId = mi.modelId
group by mi.modelId
having count(mi.mouldId) = 1;
放到服务器上面运行,报错了:
[42000][1055] Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'wd_erp.mi.mouldId' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
网上曾经查到的结果是mouldId 不是group by 的字段,这样子查询可能会产生一个modelId 对应多个mouldId 的情况, MySQL 不知道应该使用哪一个,跟在select 后的查询结果需要是group by 中的字段,或者是类似于sum count 这种的统计的结果。
思来想去了一下,写出了这样的sql:
select group_concat(mi.mouldId) as mouldId,mi.modelId
from mould_info mi
left join mould_model_info mmi on mmi.modelId = mi.modelId
group by mi.modelId
having count(mi.mouldId) = 1;
成功完成任务!
Explain 一下,共查询了两次。
查询的速度对比起来可以快1/3左右。