SQL - разъяснение между и не в комбинированном

Я новичок в SQL, так что терпите меня, если это вопрос n00b. Так что мой код работает что-то вроде следующего:

(select "Balance."CodeValue" AS "CodeValue"
       , "Balance"."OtherValue" AS "OtherValue" 
from "SomeDB"."dbo"."AValue" "Balance"
where ("Balance"."CodeValue" between 'A' and'Z' 
    or "Balance"."CodeValue" in ('ABCDEFG')) 
and "Balance"."CodeValue" NOT in ('XYZ', '1234', 'Etc') 
or "Balance"."CodeValue" between 'A' and 'Z') "Balance" 
on "SomeMatrix"."CodeValue" = "Balance"."CodeValue"

Читая его, кажется, что он проверяет, находится ли "Balance"."CodeValue" между A и Z или в "ABCDEFG", а не в "XYZ", "1234", "Etc" или между "A" и "Z". не две проверки для A и Z отменяют друг друга?

Заранее спасибо за вашу помощь.

4 ответа

Решение

Как написано выше, вы правы, первый бит ничего не делает, потому что он отрицается последним битом:

;WITH cte AS (SELECT 'XYZ' AS CodeValue
              UNION 
              SELECT 'A')
SELECT *
FROM cte
WHERE (CodeValue between 'A' and'Z'  or CodeValue in ('ABCDEFG')) 
      AND CodeValue NOT in ('XYZ', '1234', 'Etc') 
      OR CodeValue between 'A' and 'Z' 

Вернусь XYZ даже если XYZ указан в NOT IN часть.

Демонстрация: SQL Fiddle

select Balance.CodeValue AS CodeValue
       ,Balance.OtherValue AS OtherValue 
from SomeDB.dbo.AValue Balance INNER JOIN SomeMatrix
on SomeMatrix.CodeValue = Balance.CodeValue
where 
(
  Balance.CodeValue between 'A' and'Z' ----\
OR                                          -- Either of this is true
  Balance.CodeValue in ('ABCDEFG')     ----/
)     
AND                                    -- AND
(
  Balance.CodeValue 
         NOT IN ('XYZ', '1234', 'Etc')  ----\
OR                                           -- Either of this is true
  Balance.CodeValue between 'A' and 'Z' ----/
) 

Приоритет оператора NOT --> AND --> OR

Если в вашем предложении WHERE есть немного сложные / хитрые НЕ IN, AND & OR, закрывающие связанные условия в скобках () облегчает чтение и отладку вашего кода.

Нет, они не будут. SQL работает по "ограничениям" (буквально). При первом запуске запроса

select * from table

Вытаскивает все строки из таблицы. Затем, после, скажем, этот запрос

select * from table where table.column>5

Он "скрывает" (снова буквально) все строки, которые меньше или равны 5

И так далее. Так что, когда вы печатаете

select * from table table.column>5 AND table.column>5

Он скрывает те же значения, и вы получите правильный результат

РЕДАКТИРОВАТЬ: На самом деле это работает на добавление строк. Условие table.column>5 AND tavle.column>5 будет иметь значение true или false для каждой конкретной строки, и это устанавливается, если строка добавляется в результат или нет

Я думаю, что вас смущает порядок, в котором "и" и "или" оцениваются. Значения, соответствующие ЛЮБОМУ из этих трех требований, будут возвращены:

1) Balance.CodeValue НЕ в ('XYZ', '1234', 'Etc') и Balance.CodeValue между 'A' и 'Z'

2) Balance.CodeValue НЕ в ('XYZ', '1234', 'Etc') и Balance.CodeValue в ('ABCDEFG')

3) Balance.CodeValue между 'A' и 'Z'

Последнее условие "или" (Balance.CodeValue между "A" и "Z") отделено от 3 предыдущих условий, поскольку "и" оценивается перед "или". Первые 3 условия как бы склеены.

(Извините за мою неаккуратную терминологию! Я знаю логику, но не то, что нужно для ее описания.)

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