mysql where语句中 or 和 and连用注意点
在mysql中,写SQL语句时经常会遇到同时有多个条件的“或”或者“与”的情况,但是却发现查询出来的结果不是我们想要的效果,经百度,lz今天在写一条where后多个and与or时就遇到了这个问题。发现一个where语句中同时出现条件的“与”或者“或的时候”,要将多个OR用小括号括起来再和AND进行“与”,或者将多个AND用小括号括起来再与OR进行“或”,最后发现实际就是执行顺序先后的问题
先看我的SQL:
SELECT
st.id,
st.create_by,
st.create_time,
st.exam_name,
st.course_catalog_id,
st.exam sexam,
st.begin_time,
st.over_time,
st.full_score,
scc.NAME AS course_catalog_name,
st.exam_desc,
group_concat( lce.class_id ) classIdStr,
group_concat( sc.class_name ) classNameStr
FROM
st_exam st
JOIN link_class_exam lce ON lce.exam_id = st.id
LEFT JOIN st_class sc ON sc.id = lce.class_id
LEFT JOIN st_course_catalog scc ON scc.id = st.course_catalog_id
WHERE
st.create_by IN ( SELECT st_teacher.id FROM st_teacher WHERE st_teacher.role_id = 1 )
OR st.create_by = '0b5296f6-30d0-46bb-8363-6545da5d4897'
AND ( st.exam_name LIKE CONCAT( '%', '一', '%' ) OR st.exam_desc LIKE CONCAT( '%', '一', '%' ) )
GROUP BY
st.id
看的有点多,我解释一下,如图:
实际就是想查询create_by字段为** 或者 create_by为‘0b5296f6-30d0-46bb-8363-6545da5d4897’的数据,查出来是三条,但是按照我的推理应该是一条才对,因为我在最后加了and查询exam_name 或 exam_desc包含‘一’的,实际只有一条数据包含,最后经过反复观察发现,a or b and c实际的执行顺序是先执行b and c 的结果再去和a生成or,故可以将SQL修改为:
SELECT
st.id,
st.create_by,
st.create_time,
st.exam_name,
st.course_catalog_id,
st.exam sexam,
st.begin_time,
st.over_time,
st.full_score,
scc.NAME AS course_catalog_name,
st.exam_desc,
group_concat( lce.class_id ) classIdStr,
group_concat( sc.class_name ) classNameStr
FROM
st_exam st
JOIN link_class_exam lce ON lce.exam_id = st.id
LEFT JOIN st_class sc ON sc.id = lce.class_id
LEFT JOIN st_course_catalog scc ON scc.id = st.course_catalog_id
WHERE
( st.create_by IN ( SELECT st_teacher.id FROM st_teacher WHERE st_teacher.role_id = 1 ) OR st.create_by = '0b5296f6-30d0-46bb-8363-6545da5d4897' )
AND ( st.exam_name LIKE CONCAT( '%', '一', '%' ) OR st.exam_desc LIKE CONCAT( '%', '一', '%' ) )
GROUP BY
st.id
就是将or左右的两个括起来即可,或者如下
SELECT st.id,st.create_by,st.create_time, st.exam_name,st.course_catalog_id,
st.exam sexam,st.begin_time,st.over_time, st.full_score, scc.name AS course_catalog_name,
st.exam_desc, group_concat(lce.class_id) classIdStr , group_concat(sc.class_name) classNameStr
FROM st_exam st
JOIN link_class_exam lce ON lce.exam_id = st.id
LEFT JOIN st_class sc ON sc.id = lce.class_id
LEFT JOIN st_course_catalog scc ON scc.id=st.course_catalog_id
where
st.create_by in (
SELECT
st_teacher.id
FROM
st_teacher
WHERE
st_teacher.role_id = 1
OR st.id = #{createBy}
)
AND (st.exam_name LIKE CONCAT('%',#{search},'%') OR st.exam_desc LIKE CONCAT('%',#{search},'%'))
GROUP BY st.id
lzSQL较长不易观看,借用网友木子~~这篇帖子:
eg. select * from table from id=1 or id=2 and price>=10;
这条语句默认执行的是id=2并且price大于等于10的,或者是id=1。
如果加上括号:select * from table from (id=1 or id=2) and price>=10;
则这条语句执行的是id=1或id=2,并且price大于等于10。
外部链接:点我
余生还长,切勿惆怅