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。

外部链接:点我


余生还长,切勿惆怅

标签