首页 文章

有条件的where子句?

提问于
浏览
5

我想应用条件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 回答

  • 13

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

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

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

    Important

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

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

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

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

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

  • 2

    我认为你可以简化它:

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

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

  • 1

    如果条形码字段为非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, '')) + '%'
    

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

  • 0

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

    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+'%';
    
  • 0

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

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

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

  • 2

    如果列 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 来检索所有记录 . 然后你可以用 @barcode 替换 ISNULL(@barcode, '') .

  • 1

    除了ppeterka的解决方案(将导致索引/表扫描),至少有三个其他解决方案 . 如果 @barcode 不为NULL,并且如果 barcode 列上有索引,则这些解决方案可以使用 Index Seek

    解决方案#2:执行计划不会被缓存并重用:

    SELECT item 
    FROM tempTable
    WHERE @barcode IS NULL OR tempTable.barcode LIKE @barcode+'%'
    OPTION(RECOMPILE);
    

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

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

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

    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;
    

    注意:使用正确的类型和最大值 . @pBarcode 参数的长度/精度和比例 .

  • 0

    如果@barcode为null

    开始

    SELECT item FROM tempTable

    结束

    else SELECT item FROM tempTable其中tempTable.barcode LIKE @barcode'%'

相关问题