Mysql или / и приоритет?

#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. Пожалуйста, посмотрите мое дополнение к моему вопросу. это связано с отсутствием скобок, как это происходит?