Как оператор И и оператор ИЛИ могут выводить одни и те же данные

Как могло случиться, что эти два запроса разрешаются в одном и том же выводе?

SELECT *
FROM [dbo].[Orders]
where 1=1
AND year(OrderDate) = 1998 
AND MONTH(OrderDate) = 5
OR year(OrderDate) = 1997
AND MONTH(OrderDate) = 4 


SELECT *
FROM [dbo].[Orders]
where 1=1
AND (year(OrderDate) = 1998 AND MONTH(OrderDate) = 5)
OR (year(OrderDate) = 1997 AND MONTH(OrderDate) = 4)

Я ожидал, что они отложат, так как второй запрос явно генерирует 2 популяции: заказы от 05.1998 и 04.1997. Первый запрос каким-то образом делает то же самое...

Приоритет оператора важен. Если вы имеете дело с ORs, важно использовать скобки для обозначения нужной вам логики.
Larnu 20.01.2023 17:09

Кроме того, важно использовать предложения SARGable. Вы действительно должны использовать границы даты, а не использовать операторы YEAR и MONTH в столбце в WHERE.

Larnu 20.01.2023 17:09

Большая разница между w AND x AND y OR z и w AND (x AND y) OR (z) и w AND ((x and y) OR (z)). AND выигрывает.

Aaron Bertrand 20.01.2023 17:09
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы хотите использовать:

where 1=1
AND 
(
  (
         OrderDate >= '19980501'
     AND OrderDate <  '19980601'
  )
  OR
  (
         OrderDate >= '19970401'
     AND OrderDate <  '19970501'
  )
)

Как предложил Ларну, см. тему Приоритет оператора, чтобы узнать, как ведут себя AND и OR, и как управлять желаемым поведением, группируя предикаты в круглых скобках.

Если вы принимаете во внимание приоритет оператора и круглые скобки, оба ваших условия эквивалентны

WHERE (1=1 and year = 1998 and month = 5) or 
      (year = 1997 and month = 4)

Но поскольку 1=1 всегда верно, а true AND x AND y эквивалентно x AND y, вы можете удалить 1=1, таким образом, оба ваших условия на самом деле

WHERE (year = 1998 and month = 5) or
      (year = 1997 and month = 4)

Другие вопросы по теме