Почему мой запрос работает с функциями RIGHT() и LEFT(), но не с предикатом LIKE ?

#sql #sql-server

#sql #sql-сервер

Вопрос:

Я хочу выбрать строки, в которых значение столбца НЕ НАЧИНАЕТСЯ и НЕ ЗАКАНЧИВАЕТСЯ гласной. Однако, если я попытаюсь сделать это, используя LIKE предикат для определения условия в WHERE предложении, я получу ошибку времени выполнения.

 select distinct COLUMN
from TABLE
where COLUMN not like '[aeiou]%[aeiou]'
 

Если я использую для этого функции RIGHT и LEFT, мой запрос работает правильно.

 select distinct COLUMN
from TABLE where (left(COLUMN, 1) not in ('a','e','i','o','u')
and right(COLUMN, 1) not in ('a','e','i','o','u'))```
 

Однако это довольно длинная и избыточная альтернатива. Я хотел бы понять, почему первый не работает или я просто делаю что-то не так.

Ответ №1:

Эквивалентное сравнение для:

 COLUMN not like '[aeiou]%[aeiou]'
 

использует or , не and :

 where left(COLUMN, 1) not in ('a','e','i','o','u') or
      right(COLUMN, 1) not in ('a','e','i','o','u')
 

или эквивалентно:

 where not (left(COLUMN, 1) in ('a','e','i','o','u') and
           right(COLUMN, 1) in ('a','e','i','o','u')
          )
 

(потому что «не (a и b)» — это то же самое — логически — что и «не a или не b).

Рассмотрим справедливый город 'Miami' . Он соответствует not like , потому что он не начинается и не заканчивается гласной. Он просто должен провалить одно из сравнений.

Комментарии:

1. Хотя теперь я понимаю, что мой вопрос, вероятно, был немного двусмысленным, я думаю, что немного лучше понимаю проблему с моим запросом. Я бы хотел, чтобы мое условие «не нравится» выдавало мне те же строки, что и условие «не a и не b», что в результате исключало бы «Майами».

2. логическая ловушка везде. логическая ловушка везде.

3. @SamaraGama вы не можете делать то, что хотите, используя like , потому что like есть and и вам нужно or (а SQL Server не поддерживает регулярные выражения).