В чем разница между NOT (x> y) и (x <y) в запросе SQL? - PullRequest
4 голосов
/ 19 февраля 2009

В чем разница между следующим запросом:

SELECT * FROM employee  WHERE NOT(start_date > '01-JAN-1970');

и этот запрос:

SELECT * FROM employee  WHERE start_date < '01-JAN-1970';

Есть ли разница, и если да, то как NOT(x > y) используется иначе, чем (x < y). Кто-нибудь может привести пример?

Спасибо.

Ответы [ 9 ]

8 голосов
/ 19 февраля 2009

В MySQL и PostgreSQL

SELECT * FROM employee WHERE not(start_date > '01-JAN-1970')

не будет использовать INDEX на start_date, если таковые имеются, их оптимизаторы недостаточно умны.

В противном случае, если вы исправите условие, не являющееся строгим, в одном из случаев (not(start_date >= '01-JAN-1970') или start_date <= '01-JAN-1970'), запросы будут равны.

5 голосов
/ 19 февраля 2009

Не-НЕ эквивалент

SELECT * FROM employee WHERE not(start_date > '01-JAN-1970');

есть

SELECT * FROM employee WHERE start_date <= '01-JAN-1970';

не

SELECT * FROM employee WHERE start_date < '01-JAN-1970';

, поскольку это пропустит случай, когда start_date = '01 -JAN-1970 '

2 голосов
/ 19 февраля 2009

Не обращая внимания на что-либо специфичное для SQL здесь, но с логической точки зрения отрицание = (аналогично, отрицание> is <=), поэтому (x> y) и! (X

Это ясно видно, когда вы используете простой пример, такой как «Что не меньше, чем Y?». Ответ: «Y и все, что выше»;

! (X = y)

2 голосов
/ 19 февраля 2009

В вашем примере два предложения в значительной степени эквивалентны - но если вы хотите, чтобы они возвращали абсолютно одинаковые результаты, вам следует использовать < и >= (или <= и >), а не оба < и >.

NOT становится намного более полезным, когда у вас есть предложения на основе множеств. Например:

SELECT * FROM my_table
WHERE my_column NOT IN (273, 430, 9567, 8, 433, 765, 6252, 13)

SELECT * FROM my_table
WHERE my_column NOT IN (SELECT another_column FROM another_table)

Без использования NOT эти запросы станут в лучшем случае громоздкими, а в худшем - невозможными.

2 голосов
/ 19 февраля 2009

NOT () - это просто отрицание того, что находится внутри скобок. В вашем примере:

SELECT * FROM employee WHERE not(start_date > '01-JAN-1970');

Это будет соответствовать сотрудникам, чья дата начала до 1970 года. Да, вы можете отменить скобку <>, чтобы отменить ее в этом случае, но в более сложном случае или с другими операторами НЕ - единственный способ перевернуть ее. 1004 *

2 голосов
/ 19 февраля 2009

Помимо очевидного not(start_date > '01-JAN-1970') будет включать 1 января 1970 г., тогда как start_date < '01-JAN-1970' будет исключать это, я думаю, что эти утверждения идентичны.

1 голос
/ 19 февраля 2009

Вы забываете о строках, где start_date == '01 -JAN-1970 '; -)

SELECT * FROM employee WHERE start_date <= '01-JAN-1970';
1 голос
/ 19 февраля 2009

not start_date> '01 -JAN-1970 'означает, что дата начала может быть равна '01 -JAN-1970' start_date <'01 -JAN-1970 'означает, что сотрудники с '01 -JAN-1970' для даты начала не выбраны </p>

0 голосов
/ 19 февраля 2009

Я подозреваю (но не проверял), что вариант NOT также будет подбирать строки, где "start_date" - NULL - возможно, поэтому MySQL не использует индекс в этом случае.

РЕДАКТИРОВАТЬ : После прочтения Даты / Дарвена Руководство по стандарту SQL этот ответ неверен. Null вводит третье состояние в операторы сравнения (см. Стр. 240, 241 или четвертое издание).

Однако я собираюсь оставить этот ответ, потому что вполне возможно, что тот, кто написал это выражение, думал так же, как и я, и пытался захватить нулевые значения. Или возможно, что конкретная СУБД не соответствует стандарту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...