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 условия как бы склеены.
(Извините за мою неаккуратную терминологию! Я знаю логику, но не то, что нужно для ее описания.)