Условие фильтра не работает должным образом в моем запросе T-SQL

#sql-server #tsql #filter #multiple-conditions

#sql-server #tsql #Фильтр #несколько условий

Вопрос:

Я использую SQL Server 2016, и в моем запросе есть следующая строка кода:

 AND NOT (f.Name = 'ABC Ltd' and a.PackagePlanCode like 'CO%' and c.PropertyCode = 'BIC')
  

Мне нужно, чтобы ВСЕ условия выполнялись. То есть, f.Name должно быть равно ‘ABC Ltd’ И.PackagePlanCode ДОЛЖЕН начинаться с ‘CO …’, а код свойства ДОЛЖЕН быть ‘BIC’.

Я вижу неустойчивое поведение в моем запросе с приведенной выше строкой кода. Иногда, даже если 2 условия соответствуют, это исключает эту запись.

У меня есть запись в моей базе данных, которая имеет следующее:

Имя = XYZ ltd

PackagePlanCode = COHB

PropertyCode = BIC

Приведенная выше запись НЕ должна была быть исключена из моего результирующего набора, потому что у нее есть только 2 критерия (а именно PackagePlanCode и PropertyCode), которые соответствуют моему фильтру, и все же она исключена из результирующего набора.

Есть ли лучший способ написать этот код, чтобы я был уверен, что он исключает записи, которые удовлетворяют только ВСЕМ 3 условиям, указанным в нем?

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

1. В вашем скопированном коде перед круглыми скобками стоит «И НЕ». Таким образом, это полностью меняет логику предложения WHERE. Почему бы вам не удалить все это. Только внутри круглых скобок после WHERE

2. У меня есть другие условия, которые существуют после моего предложения WHERE. Это всего лишь один из них, и здесь я ИСКЛЮЧАЮ записи, которые соответствуют этим 3 критериям.

3. И вы имеете в виду, что в результирующем наборе есть строки, соответствующие этим критериям? Может ли это быть проблема с сопоставлением, что-то связанное с varchar или nvarchar?

4. В результирующем наборе я НЕ вижу записи, в которой имя является чем-то иным, чем ABC Ltd, но у которых есть PackagePlanCode, начинающийся с ‘CO …’ и PropertyCode как ‘BIC’. Для упрощения у меня есть запись в моей базе данных, которая выглядит следующим образом: Name = XYZ ltd PackagePlanCode = COHB PropertyCode = BIC Приведенная выше запись НЕ должна была быть исключена из моего набора результатов, потому что у нее есть только 2 критерия (а именно PackagPlanCode и PropertyCode), которые соответствуют моему фильтру. Надеюсь, я сделал это несколько понятнее.

5. @LukStorms Я снова протестировал, удалив все остальные фильтры в моем запросе и сохранив этот. По-прежнему не отображается запись, о которой я упоминал выше.

Ответ №1:

Это не предназначено в качестве решения.
(Я подозреваю, что соединения или что-то в других условиях)

Просто добавляю пример, чтобы показать, что предложение WHERE работает так, как от него можно было ожидать. Если в любом случае нет нулей.

 declare @T table (id int identity, num1 int, var1 varchar(30), var2 varchar(30), var3 varchar(30));

insert into @T (num1, var1, var2, var3) values 
(1,'Foo','Bar','Baz'),
(1,'Foo','Bar','CO Baz'),
(1,'Bar','Bar','CO Baz'),
(1,'Foo','Bar',null),
(1,'Foo',null,'CO Baz');

-- Query 1
select * from @T
where num1 > 0
and NOT (var1 = 'Foo' and var2 = 'Bar' and var3 like 'CO%');

-- Query 2
select * from @T
where num1 > 0
and NOT (coalesce(var1,'') = 'Foo' and coalesce(var2,'') = 'Bar' and coalesce(var3,'') like 'CO%');

-- Query 3
select * from @T
where num1 > 0
and IIF(var1 = 'Foo' and var2 = 'Bar' and var3 like 'CO%',1,0) = 0;
  

Запрос 1 возвращает

 id  num1  var1  var2  var3
1   1     Foo   Bar   Baz
3   1     Bar   Bar   CO Baz
  

Запрос 2 и 3 возвращает

 id  num1  var1  var2  var3
1   1     Foo   Bar   Baz
3   1     Bar   Bar   CO Baz
4   1     Foo   Bar   NULL
5   1     Foo   NULL  CO Baz