SQL не нравится - не работает - PullRequest
0 голосов
/ 03 августа 2011

ОБНОВЛЕНИЕ 2:

В одной из строк в столбце closed_by содержится null. Если я заменю ноль на текст, запрос начнет работать, но он не будет работать с null. Кажется, проблема в null, но запрос должен возвращать строки, которые тоже имеют null, поскольку pqr не равно null.

ОБНОВЛЕНИЕ 1:

Я также пытался set @user = 'pqr', но это не имеет значения. Он по-прежнему возвращает 0 строк, когда должен возвращать 1 строку, поскольку 1 из строк не содержит pqr.

ОРИГИНАЛЬНЫЙ ВОПРОС:

Я пытаюсь вернуть строки, которые не содержат предоставленный идентификатор:

declare @user varchar(3)
set     @user = 'pqr'

select * from table1 where not( closed_by like @user )

closed_by содержит данные типа

abc,def,ghi,jkl,mno

Но это не дает мне ошибок и не возвращает данных, оно должно возвращать одну строку, так как pqr не находится в 1 строке.

Не уверен, что я делаю неправильно.

Ответы [ 6 ]

3 голосов
/ 03 августа 2011

Возможно, вы захотите проверить синтаксис оператора LIKE - он принимает шаблон , поэтому вам нужно будет использовать что-то вроде этого:

declare @user varchar(5)
set @user = '%pqr%'

'%' является символом подстановки и соответствует любой строке со знаком Zeor или более символов.

К вашему сведению - SQL Server не сможет использовать индексы с шаблоном LIKE, который начинается с подстановочного знака, поэтому вы можете обнаружить, что ваш запрос плохо работает с большими наборами данных.

2 голосов
/ 03 августа 2011

NULL неизвестно, и поэтому неизвестно, является ли он вашим шаблоном или нет. Вы можете легко решить эту проблему, используя:

DECLARE @user VARCHAR(5) = '%pqr%';    
SELECT ... WHERE COALESCE(closed_by, '') NOT LIKE @user;

А на самом деле, чтобы быть более точным, вы, вероятно, хотите:

DECLARE @user VARCHAR(7) = '%,pqr,%';    
SELECT ... WHERE COALESCE(',' + closed_by + ',', '') NOT LIKE @user;

Таким образом, если у вас позже будут данные типа 'trv,pqrs,ltt', он не вернет ложное срабатывание.

Однако, сказав все это, рассмотрели ли вы, как хранить это в более нормализованном виде? Хранение разделенных запятыми списков может быть очень проблематичным, и я могу заверить вас, что это не будет последней проблемой, с которой вы столкнетесь при работе с данными, структурированными таким образом.

1 голос
/ 03 августа 2011

Вам необходимо использовать подстановочные знаки % и _ при использовании LIKE.Без них у вас просто есть WHERE NOT (closed_by = @user).

Также будьте осторожны со случайными совпадениями.Например, LIKE '%a%' будет соответствовать вашему примеру записи.В таких случаях я стараюсь, чтобы списки с разделителями-запятыми также имели запятые в начале и в конце.Такие как;',abc,def,ghi,jkl,mno,' LIKE '%,ghi,%'

Но, более того, вы используете реляционную базу данных.Вам будет лучше с каждой записью, поскольку она является собственной записью в нормализованной структуре.Хотя это дает отношения 1: много, а не отношения 1: 1, вы получаете преимущества ИНДЕКСОВ и гораздо большую гибкость в своих запросах.(Ваш пример LIKE не может использовать индекс.)

ОТВЕТИТЬ НА ОБНОВЛЕНИЕ 2:

Будьте осторожны с тем, как вы предполагаете, что логика NULL работает.

  • Результат NULL LIKE '%pqr%' равен NULL
  • Результат NOT (NULL) равен NULL

Вам необходимо изменить код для использования WHERE NOT (ISNULL(closed_by, '') LIKE '%pqr%')

1 голос
/ 03 августа 2011

Вам необходимо включить подстановочный знак:

declare 
@user varchar(5) 
set @user = '%pqr%'  

select * 
from table1 
where isnull(closed_by, '') not like @user
0 голосов
/ 03 августа 2011

Мне кажется, что вы действительно ищете эквивалентность, а не подстановочные совпадения.Попробуйте это:

select * from table1 where closed_by <> @user
0 голосов
/ 03 августа 2011

Попробуйте:

select * from table1 where closed_by not like @user

И вам может понадобиться добавить соответствующие символы «%», чтобы сообщить SQL Server, какую часть значения искать.Например, 'pqr%'

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