【问题标题】:WHERE clause match or nullWHERE 子句匹配或为空
【发布时间】:2021-05-18 17:04:30
【问题描述】:

我已经搜索、搜索、测试和测试,但我似乎找不到答案。

这是设置。我有 4 个参数可以传入:

  1. 匹配表中的列
  2. 参数和表列为空
  3. 参数不匹配,但关联的表列为空

我试过了:

  • PCN = ( CASE WHEN PCN = @group THEN @PCN 当 PCN 为 NULL 时,则为 NULL 结束)

    1. 处理,2. 不处理,3. 不处理
  • (PCN=@PCN 要么 PCN 为空)

    1. 不处理,2.不处理 3.不处理
  • (IsNull(PCN,'none') = IsNull(@PCN,'none'))

    1. 把手,2.把手,3.不把手

由于最后一个是处理场景 3 的唯一一个,这里有关于那个的更多细节。

DECLARE @bin varchar(6) = '123456'
   , @PCN varchar(50) = 'abc'
   , @Group varchar(50) = '0.0'
   , @NDC = '01234567891'
        
select * from dbo.Insurance
WHERE (IsNull([Group],'none') = IsNull(@group,'none'))
       and (IsNull(PCN,'none') = IsNull(@PCN,'none'))
       and (IsNull(BIN,'none') = IsNull(@bin,'none'))
       and (IsNull(NDC,'none') = IsNull(@NDC,'none') )
order by [Group] desc, PCN desc, BIN desc, NDC;

此查询不返回任何结果。我的期望是返回 Bin、Group 和 NDC 匹配且 PCN 为 NULL 的行。非常感谢您提供的任何见解!

更新:

RowId BIN PCN Group NDC
1 123456 abc 0.0 01234567891
2 123456 NULL 0.0 01234567891
  • 场景 1 - PCN 列 = PCN 变量,应该返回 rowID 1
  • 场景 2 - PCN 列和 PCN 变量为空,应返回 rowID 2
  • 场景 3 - PCN 变量 = 123,应该返回 rowID 2

【问题讨论】:

  • 请以文本形式提供示例数据和所需输出
  • 您为什么使用不受支持的 SQL Server 版本?
  • 也许我遗漏了一些东西,但我认为您想要 ([Group] = @Group OR [Group] IS NULL) 并且对于其他标准也是如此。
  • @DanGuzman 原来就是这样 - 它不适用于第一种或第二种情况。它返回的行太多。
  • @GordonLinoff 我不是 DBA,也不是负责做出此类决定。

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


【解决方案1】:

解决方案 1:

((Group IS NULL AND @group IS NULL) OR (Group IS NOT NULL AND @group IS NOT NULL AND Group = @group ))
and ...

解决方案 2:

(Group= @group) OR (ISNULL(Group, @group) IS NULL)
and ...

【讨论】:

  • 这些解决方案不涵盖第三种情况,参数不匹配但关联的表列为空。有关更多说明,请参阅更新后的问题。
【解决方案2】:

每个参数可以有 3 个 OR

select      *
from        dbo.Insurance
where       ([Group] is null or @Group is null or   [Group] = @Group)
and         (PCN is null or @PCN is null or PCN = @PCN)
and         (BIN is null or @bin is null or BIN = @bin)
and         (NDC is null or @NDC is null or NDC = @NDC)
order by    [Group] desc
            , PCN desc
            , BIN desc
            , NDC;

【讨论】:

    【解决方案3】:
    WHERE 
        (colA = @a OR colA IS NULL)
    
    1. 值匹配:接受基于colA = @a
    2. 两者都是NULL:接受基于colA IS NULL
    3. colA 为 NULL:也接受基于 colA IS NULL

    但我们还需要确保没有其他情况通过:

    1. 两者都有值,但它们不匹配:将不接受基于任何一半的值。
    2. colA 不为 NULL,@a 为 NULL:也不通过

    【讨论】:

      【解决方案4】:

      我再次与我们的团队讨论了业务需求。稍微调整一下,以防万一将来有人遇到类似的事情,这里是最终的要求和解决方案:

      1. 参数和列相同
      2. 参数和列均为空
      3. 列有通配符 (*)
      DECLARE @bin varchar(6) = '123456'
       , @PCN varchar(50) = 'abc'
         , @Group varchar(50) = '0.0'
         , @NDC = '01234567891'
              
      select * from dbo.Insurance
      WHERE ((IsNull([Group],'none') = IsNull(@group,'none')) OR [Group] = '*')
           and
           ((IsNull(PCN,'none') = IsNull(@PCN,'none')) OR PCN = '*')
           and 
           ((IsNull(BIN,'none') = IsNull(@bin,'none')) OR BIN = '*')
           and
           ((IsNull(NDC9,'none') = IsNull(@NDC9,'none') ) OR NDC9 = '*')
      order by [Group] desc, PCN desc, BIN desc, NDC;
      

      感谢大家的cmets!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-09
        • 2016-04-17
        • 2015-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-03
        相关资源
        最近更新 更多