【问题标题】:Using ISNULL in where Clause doesn't return records with NULL field在 where 子句不返回具有 NULL 字段的记录中使用 ISNULL
【发布时间】:2013-10-28 07:27:04
【问题描述】:

表格:

ID     AppType     AppSubType   Factor
1   SC  CD      1.0000000000
2   SC  CD      2.0000000000
3   SC  NULL    3.0000000000
4   SC  NULL    4.0000000000

查询:

declare @ast varchar(10)

set @ast = null

select *
from tbl
where AppType = 'SC' and AppSubType = ISNULL(@ast, AppSubType)

结果:

ID  AppType AppSubType  Factor
1   SC  CD  1.0000000000
2   SC  CD  2.0000000000

问题:

这个查询不应该返回所有 4 条记录,而不仅仅是前 2 条吗?

【问题讨论】:

  • 看起来像 SQL。请为此添加标签。在您编辑标签时,请为您使用的任何数据库系统(例如 Oracle、SQL Server、MySQL 等)添加一个合适的标签
  • 另外 - 你想做什么?它是以下一种还是两种:a) 返回与@ast 匹配或具有NULL 的所有行,或者b) 如果@astNULL,则返回具有NULL 的行。具体来说,当@ast 不是 NULL 时,预期的行为是什么。
  • why is null not equal to null false 的可能副本(嗯,足够接近)。
  • 查询在存储过程中。我想要的是,如果我不传递 AppSubType 参数(作为 null 传递),它应该返回所有 4 条记录(就像在 where 条件下不考虑 AppSubType)

标签: sql sql-server-2008 isnull


【解决方案1】:

@ast 显然是 null 并且 Isnull 会与其他值交换 null,所以你不应该期望 @ast 不为 null。如果您的 AppSubType 为 null ,则结果为 null 但 AppSubType=null 并不意味着因为 AppSubType is null 为真。因为 null 不是一个值,所以它不能与 equal 一起使用。 对于您的预期结果,此代码将起作用。

declare @ast varchar(10)

set @ast = null

select *
from tbl
where AppType = 'SC' and (AppSubType = ISNULL(@ast, AppSubType) Or AppSubType is null)

【讨论】:

  • thanx amirreza,这种方法有效且简单。但为了清楚起见,为什么它不使用原始查询返回最后 2 条记录?前任。当 @ast 作为 null 传递时,条件 AppSubType = ISNULL(@ast, AppSubType) 变为 AppSubType = AppSubType
  • @user1842048 - 答案暗示了原因,但可能会更清楚。但是,请注意,无论@ast 是什么,此版本都会返回AppSubType 为空的所有行...
  • 看,当@ast传为null时,条件AppSubType = ISNULL(@ast, AppSubType)就变成了AppSubType = AppSubType,查询当时使用了rows,所以变成了AppSubType =null this not意味着比 AppSubType 为 null 这只是一个无意义的比较,因此不返回最后 2 行为 null。
  • @AmirrezaKeshavarz - 注意一定是“无意义的比较”;对于null == null 比较,大多数计算机语言都会返回true。如果 OP 具​​有其中一种语言的背景,那么 SQL 函数的方式可能会令人惊讶(尤其是考虑到他正在比较同一列......)
  • Sql最初是Sequel Stand for English结构化查询语言,后来改为sql,非常接近英文。 null 也不是一个值,它只是一个缺失值的符号。所以 = 不能对其进行操作 tsql 有一个结构可以理解。
【解决方案2】:

你可以在where子句中写一个case条件为:

declare @ast varchar(10)

set @ast = null

select *
from tbl
where AppType = 'SC' and 1=
      case when isnull(@ast ,'') = '' and isnull(AppSubType ,'') = '' then 1
           when AppSubType = ISNULL(@ast, AppSubType) then 1 
           else 0
      end

【讨论】:

  • ...这里有一个语言功能真的很有帮助。即<column name> IS NULL 检查。 CASE 语句而不是仅使用布尔逻辑是什么?
【解决方案3】:

请理解下面博客中解释的 ISNULL 的行为。

isnull 函数中的第一个表达式是列值或某个结果的表达式。

ISNULL Explored in Detail

代码看起来像一个搜索功能。如果未给出该值,则将它们替换为数据库中的任何内容,如果给出,则仅提取匹配的那些记录。

【讨论】:

    猜你喜欢
    • 2011-06-09
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    • 2011-11-17
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    相关资源
    最近更新 更多