#php #mysql
#mysql #оператор-приоритет
Вопрос:
Мне интересно, как работает или / и?
Например, если я хочу получить все строки, где display = 1
Я могу просто сделать WHERE tablename.display = 1
и если я хочу, чтобы все строки отображали = 1 или 2
Я могу просто сделать WHERE tablename.display = 1 or tablename.display = 2
Но что, если я хочу получить все строки, где display = 1 или 2 и где любой из содержимого, тегов или заголовка содержит hello world
Как бы логика сработала для этого?
Select * from tablename
where display = 1 or display = 2 and content like "%hello world%" or tags like "%hello world%" or title = "%hello world%"
Было бы моим предположением. но тогда я могу прочитать это несколькими способами.
Считывается ли это как:
(display = 1 or display = 2) and (content like "%hello world%" or tags like "%hello world%" or title = "%hello world%")
или как
((display = 1 or display = 2) and (content like "%hello world%")) or (tags like "%hello world%" or title = "%hello world%")
и т.д.
Комментарии:
1. dev.mysql.com/doc/refman/5.5/en/operator-precedence.html
2. Эти вещи изучаются на ваших ранних курсах C / C .
3. Тогда, я думаю, мне следует записаться на полный курс C / C , просто чтобы узнать приоритет операторов :/
Ответ №1:
В документации MySQL есть хорошая страница с информацией о том, какие операторы имеют приоритет.
С этой страницы,
12.3.1. Приоритет оператора
Прецеденты операторов показаны в следующем списке, от самого высокого приоритета до самого низкого. Операторы, которые отображаются вместе в строке, имеют одинаковый приоритет.
INTERVAL BINARY, COLLATE ! - (unary minus), ~ (unary bit inversion) ^ *, /, DIV, %, MOD -, <<, >> amp; | = (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN BETWEEN, CASE, WHEN, THEN, ELSE NOT amp;amp;, AND XOR ||, OR = (assignment), :=
Итак, ваш исходный запрос
Select
*
from tablename
where
display = 1
or display = 2
and content like "%hello world%"
or tags like "%hello world%"
or title = "%hello world%"
будет интерпретироваться как
Select
*
from tablename
where
(display = 1)
or (
(display = 2)
and (content like "%hello world%")
)
or (tags like "%hello world%")
or (title = "%hello world%")
Если сомневаетесь, используйте круглые скобки, чтобы прояснить свои намерения. Хотя информация на странице MySQL полезна, это может быть не сразу очевидно, если запрос когда-либо повторится.
Вы могли бы рассмотреть что-то вроде следующего. Обратите внимание, что я изменил title = "%hello world%"
на title like "%hello world%"
, поскольку это лучше соответствует цели, которую вы описали.
Select
*
from tablename
where
(
(display = 1)
or (display = 2)
) and (
(content like "%hello world%")
or (tags like "%hello world%")
or (title like "%hello world%")
)
Ответ №2:
Запустите этот запрос:
select 1 or 1 and 0
Если это отображается как 1
, то это означает, что приоритет равен:
select 1 or (1 and 0)
если это выходит 0
, то приоритет равен:
select (1 or 1) and 0
Спойлер: это выходит 1
То есть AND
s вычисляются перед OR
s, или, как я люблю говорить, ANDs более жесткие.
Ответ №3:
Вам нужно использовать квадратные скобки для ваших нескольких OR
условий. И для display = 1 OR display = 2
вы можете использовать display IN(1,2)
. Попробуйте это:
SELECT * FROM tableName
WHERE display IN (1,2)
AND (content LIKE "%hello world%"
OR tags LIKE "%hello world%"
OR title LIKE "%hello world%")
Для получения дополнительной информации посмотрите на MySQL: приоритет операторов
Ответ №4:
на всех серверах SQL AND
имеет приоритет над OR
, поэтому просто не забудьте заключить в скобки ваши OR
s:
select * from tablename
where (display = 1 or display = 2)
and (content like "%hello world%"
or tags like "%hello world%"
or title = "%hello world%")
кстати, (display = 1 or display = 2)
эквивалентно display in (1, 2)
.
Комментарии:
1. Пожалуйста, посмотрите мое дополнение к моему вопросу. это связано с отсутствием скобок, как это происходит?