有条件的where子句?

时间:2013-09-11 09:30:33

标签: sql sql-server sql-server-2008 where where-clause

我想应用条件where子句即如果我的barcode参数为null,那么我想获取所有记录,如果它带有值,那么我想只获取第二部分的匹配记录我能够获取匹配的记录但我仍然坚持获取所有记录,如果我已经尝试了空值,

 SELECT item 
 FROM tempTable
 WHERE 
  ((ISNULL(@barcode,0)=1)
      // but this is not fetching all the records if barcode is null 
   OR
   ISNULL(@barcode,0!= 1 AND tempTable.barcode LIKE @barcode+'%'))
      //THis is working perfect 

所以任何帮助都会很棒

8 个答案:

答案 0 :(得分:14)

我可能误解了你的要求,但逻辑OR运算符可能有所帮助:

SELECT item 
 FROM tempTable
 WHERE 
 @barcode IS NULL OR tempTable.barcode LIKE @barcode+'%'

如果@barcodeNULL,则返回所有记录,如果不是NULL,则返回满足条件LIKE @barcode+'%'的所有记录

重要

另外,请记住,使用OR运算符在与多个复杂条件一起使用时似乎会产生有趣的结果,并且未在括号中正确包含:

<A> AND <B> AND <C> OR <D> AND <E> AND <F>

最有可能实际上被表述为:

(<A> AND <B> AND <C>) OR (<D> AND <E> AND <F>)

请记住,解析器不知道你想要实现什么,你必须正确描述你的意图......

答案 1 :(得分:2)

我认为你可以将其简化为:

  SELECT item 
 FROM tempTable
 WHERE @barcode IS NULL OR tempTable.barcode LIKE @barcode+'%'

因此,当@barcode为null时,您将获得所有内容 - 即不需要执行的Where部分。如果@barcode有值,则会执行Like。

答案 2 :(得分:2)

如果条形码字段为非null,则这是我将使用的方法 -

SELECT item 
FROM tempTable
WHERE barcode like isnull(@barcode, barcode) + '%'

如果@barcode为null,则返回所有记录,如果它为非null,则仅返回匹配的记录。

如果条形码字段可以为空,那么 -

SELECT item 
FROM tempTable
WHERE isnull(barcode, '') like isnull(@barcode, isnull(barcode, '')) + '%'

与第一个相同,但在这里我们在进行比较之前将条形码字段中的空值转换为空字符串。

答案 3 :(得分:1)

另一个答案和对赏金的尝试

declare @barcode nvarchar(10) -- chose nvarchar not necessarily should be nvarchar
select @barcode= NULL
--select @barcode='XYZ'
if @barcode is null
select item from temptable;
else
select item from temptable where temptable.barcode like @barcode+'%';

答案 4 :(得分:1)

如果我必须这样做,我会像

那样做
SELECT item 
 FROM tempTable
 WHERE 
( ( ISNULL(@barcode,'') <> '')  AND ( tempTable.barcode LIKE @barcode+'%' ) )

( ISNULL(@barcode,'') <> '')还会检查变量是否为空,然后它不应返回任何内容。但是,如果您只检查null,那么在@barcode为空的情况下,您将从item中选择所有tempTable

答案 5 :(得分:0)

如果列barcode不可为空,则可以大大简化查询。 这是基于模式'%'匹配任何字符串的事实;甚至是一个空的(即零长度)字符串。 因此,以下WHERE子句匹配所有记录:

WHERE barcode LIKE '%'

您可能会注意到,这与您用于过滤特定条形码上的记录的WHERE子句非常相似:

WHERE barcode LIKE @barcode + '%'

事实上,它们非常相似,我们也可以为这两种情况使用单个WHERE子句;毕竟,'' + '%'等于'%'

IF @barcode IS NULL SET @barcode = ''
SELECT item FROM tempTable WHERE barcode LIKE @barcode + '%'

还有一个更短的版本,它保留了@barcode的原始值:

SELECT item FROM tempTable WHERE barcode LIKE ISNULL(@barcode, '') + '%'

如前所述,仅当列barcode不可为空时,此方法才有效。 如果列barcode可以为空(并且您真正对barcode IS NULL)的记录感兴趣,那么以下查询可能对您有用:

SELECT item FROM tempTable
WHERE ISNULL(barcode, '') LIKE ISNULL(@barcode, '') + '%'

但是,这个版本有两个缺点:

  • 可能执行速度要慢得多,因为查询优化器可能无法从列barcode上的索引中受益。
  • 如果@barcode = '',那么它不仅会匹配非空条形码,还会匹配barcode IS NULL的记录;这是否可以接受,取决于你。

最后一个简化:您可能希望与外界达成共识,他们应该设置@barcode = ''而不是NULL来检索所有记录。然后,您可以将ISNULL(@barcode, '')替换为@barcode

答案 6 :(得分:0)

如果@barcode为空

开始

SELECT item FROM tempTable

否则 SELECT item FROM tempTable,其中tempTable.barcode LIKE @barcode +'%'

答案 7 :(得分:0)

除了ppeterka的解决方案(将导致索引/表扫描)之外,还有至少三种其他解决方案。如果Index Seek不是NULL,这些解决方案可以使用@barcode,如果barcode列上有索引,也可以使用SELECT item FROM tempTable WHERE @barcode IS NULL OR tempTable.barcode LIKE @barcode+'%' OPTION(RECOMPILE);

解决方案#2:执行计划未被缓存并重复使用:

IF @barcode IS NULL
    SELECT item 
    FROM tempTable;
ELSE
    SELECT item 
    FROM tempTable
    WHERE tempTable.barcode LIKE @barcode+'%';

解决方案#3:执行计划被缓存(如果可选参数的数量很小,则可以使用它):

DECLARE @SqlStatement NVARCHAR(MAX);
SET @SqlStatement = N'
SELECT item 
FROM tempTable
WHERE 1=1 '
+ CASE WHEN @barcode IS NULL THEN N'' ELSE N'AND tempTable.barcode LIKE @pBarcode+''%''; ' END; 
-- + CASE WHEN @anotherparam IS NULL THEN N'' ELSE 'AND ...' END ;

EXEC sp_executesql @SqlStatement, N'@pBarcode VARCHAR(10)', @pBarcode = @barcode;

解决方案#4:执行计划被缓存(如果可选参数的数量很高,则可以使用它):

@pBarcode

注意:使用正确的类型和最大值。长度/精度&amp; {{1}}参数的比例。