Почему мой SQL возвращает ненужные записи с моим оператором OR в предложении Where - PullRequest
1 голос
/ 29 июня 2019

Допустим, у меня есть эта таблица, называемая подписками в Redshift (http://sqlfiddle.com/#!17/c6c53/1):

    id  | subscription_type | subscription_origin
-------------------------------------------------
    100 | monthly           | trial_page
    101 | annual_trial      | sales_rep
    102 | monthly           | sales_rep
    103 | annual            | sales_rep

возвращение всех строк без «пробной» в типе подписки выглядит правильно:

select * from subscriptions where subscription_type NOT LIKE '%trial%'
 http://sqlfiddle.com/#!17/c6c53/2

но яЯ хочу вернуть все строки, которые не имеют 'trial' в или subscription_type или subscription_origin.

Итак, я написал этот запрос:

SELECT * 
FROM subscriptions 
WHERE subscription_type NOT LIKE '%trial%' OR
subscription_origin NOT LIKE '%trial_page%'

, но http://sqlfiddle.com/#!17/c6c53/3 возвращает все строки.

как исключить все строки с пробным присутствием в строке?

1 Ответ

4 голосов
/ 29 июня 2019

Вы должны использовать AND:

SELECT * 
FROM subscriptions 
WHERE subscription_type NOT LIKE '%trial%' 
  AND subscription_origin NOT LIKE '%trial_page%';

Демонстрация sqlfiddle

Это пример, когда полезно знание булевой алгебры:

Законы де Моргана :

Правила могут быть выражены на английском языке как:

  • отрицание дизъюнкции - это соединение отрицаний; и

  • отрицание соединения - это дизъюнкция отрицания;

Предположим, вы хотите найти строки, которые col1 LIKE A OR col2 LIKE B:

-- assuming that both columns are not nullable
NOT(col1 LIKE A OR col2 LIKE B) <=> col1 NOT LIKE A AND col2 NOT LIKE B
...