我有一个奇怪的问题,一个 select
. WHERE
子句中的顺序是否可能影响结果?
这是我的选择:
select u.userName, u.fullName, g.uuid as groupUuid, g.name as `group`,
m.number as module, count(distinct b.uuid) as buildCount, max(b.datetime),
count(distinct e.buildId) as errorBuildCount, e.id as errorId
from User u
inner join GROUP_USER GU on GU.user_id = u.id
inner join `Group` g on g.id = GU.group_id
inner join Course c on c.id = g.courseId
left outer join Build b on b.userId = u.id
left outer join Module m on m.id = b.moduleId
left outer join Error e on e.buildId = b.id
where c.uuid = 'HMUUcabR1S4GRTIwt3wWxzCO' and g.uuid = 'abcdefghijklmnopqrstuvwz'
group by u.userName,m.number,c.uuid, g.uuid
order by g.id asc, u.fullName asc, m.number asc
这将重现此结果:http://dl.dropbox.com/u/4892450/sqlSelectProblem/select1.PNG
当我使用这个条件时:
where g.uuid = 'abcdefghijklmnopqrstuvwz' and c.uuid = 'HMUUcabR1S4GRTIwt3wWxzCO'
(不同的顺序)我得到了不同的结果(见 errorId
专栏):http://dl.dropbox.com/u/4892450/sqlSelectProblem/select2.PNG
请你帮助我好吗?整个选择是错误的,还是一个 mysql
错误?
3 回答
结果之间的唯一区别是
errorId
列 . sql标准(sql-92标准,检查the link)不允许使用未分组和未分页的列,甚至不会在大多数数据库引擎中运行 . 因此,没有指定引擎在这种情况下的行为 . 根据docs(感谢Marcus Adams):您可以将
errorId
作为聚合值:或将其包含在
GROUP BY
列表中:然后您的查询结果应该是稳定的 .
Further reading:
Why does MySQL add a feature that conflicts with SQL standards? - sql标准和mysql实现之间差异的详细解释 . (感谢GarethD)
你的代码中有两个不同的JOIN树,主要是:
这样的构造导致未定义的结果,特别是如果一个分支中的连接结果具有与另一个分支中不同数量的匹配记录 . MySQL必须尝试填写缺失的位,并猜测 . 更改
WHERE
子句的顺序可以并且将更改完整结果,因为您正在改变mysql猜测的方式 .在聚合之前按所有列分组 . 最佳实践......在大多数情况下 . 并且很可能会扭曲你的答案......