Подтвердить что ты не робот

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

Мне интересно, как и/или работает?

Например, если я хочу получить все строки, где display = 1

Я могу просто сделать WHERE tablename.display = 1

и если мне нужны все строки, где display = 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%")

и др.

4b9b3361

Ответ 1

В документации MySQL есть хорошая страница с информацией о том, какие операторы имеют приоритет.

С этой страницы

12.3.1. Приоритет оператора

Приоритеты операторов показаны в следующем списке: от наивысшего приоритета до самого низкого. Операторы, которые показаны вместе на линии, имеют одинаковый приоритет.

INTERVAL
BINARY, COLLATE
!
- (unary minus), ~ (unary bit inversion)
^
*, /, DIV, %, MOD
-, +
<<, >>
&
|
= (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
BETWEEN, CASE, WHEN, THEN, ELSE
NOT
&&, 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

Вам нужно использовать скобки для нескольких условий 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: Приоритет оператора

Ответ 3

Запустите этот запрос:

select 1 or 1 and 0

Если это выглядит как 1, то это означает, что приоритет:

select 1 or (1 and 0)

если он выходит 0, тогда приоритет:

select (1 or 1) and 0

Спойлер: он выходит 1

То есть, AND оценивается до OR s или, как мне хотелось бы сказать, ANDs являются более липкими.

Ответ 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%")


btw (display = 1 or display = 2) эквивалентно display in (1, 2).