SQL 条件匹配 int / varchar类型参数检索区别 传‘‘空字符串时不筛选方法

起因是写了一个需要检索int类型字段的条件匹配,原意是参数@Year传''空时Year字段不进行筛选,然后发现查询结果是该字段的数据都查询不到。

Year列本身包含一些为NULL的数据。

Decalre @Year INT

WHERE ISNULL(Year, '') = @Year    --原来写的

当我修改成case when 筛选时,又只能筛选到有数值的数据,无数值(null)的数据全部筛选不到。(此处有一个注意点,INT类型的参数传'',实际上参数的数值会自动转换成0

WHERE (Year = CASE WHEN @Year = 0 THEN Year ELSE @Year END)

后来发现问题出现在这,匹配逻辑存在误区:
 

在SQL中,NULL代表一个未知的或缺失的值。当你在WHERE子句中进行比较操作时,如果比较的任一侧是NULL,那么整个比较表达式的结果将不是TRUEFALSE,而是NULL。在SQL的逻辑中,NULL不等同于FALSE,而是表示“未知”,因此它不会满足WHERE子句的条件。

例如,假设你有一个名为MyColumn的列,其中有一些NULL值,如果你运行以下查询:

SELECT *
FROM MyTable
WHERE MyColumn = 123;

那么所有MyColumn列中值为123的行将被选中,而MyColumn列中的NULL值将不会被选中,因为NULL = 123的结果是NULL,不是TRUE

同样地,如果你运行:

SELECT *
FROM MyTable
WHERE MyColumn = MyColumn;

你可能期望这个查询返回所有行,因为任何值和它自己比较都应该是相等的。然而,对于MyColumn中的NULL值,NULL = NULL的结果也是NULL,而不是TRUE。因此,这个查询不会返回那些MyColumn值为NULL的行。

回到我的查询,当@Year参数为0时,我希望返回所有记录,而不考虑Year的值。但是如果Year字段的值恰好NULL,那么这个比较会变成NULL = NULL,其结果是NULL,不满足WHERE子句的条件。为了确保即使在YearNULL的情况下也能选中所有记录,我需要添加OR @Year = 0条件,这样当@tYear为0时,无论Year的值是什么,包括NULL都会被检索到。

当在 SQL 的 WHERE 子句中使用 OR 时,是在指定两个或多个条件中只要有一个条件满足,整个 WHERE 子句就会被认为是真(TRUE),因此查询会返回那行数据这个OR条件都会为TRUE,从而包含所有记录。

--修改为
WHERE (Year = CASE WHEN @Year = 0 THEN Year ELSE @Year END OR @Year = 0)

这是一种常见的技巧,用于在参数值应触发“无过滤”行为时,确保查询不会由于字段中的NULL值而排除任何记录。


varchar类型参数筛选:

WHERE FName LIKE '%' + @Name + '%'

当使用 LIKE 操作符与一个包含通配符 % 的字符串进行比较时,如果变量为空字符串(''),那么表达式会变成:

WHERE ts.FName LIKE '%%'

--这相当于
WHERE ts.FName LIKE '%'

在 SQL 中,百分号 % 是一个通配符,它匹配任何字符序列(包括空字符序列)。因此,当 @Name 是空字符串时,LIKE '%' 会匹配 ts.FName 中的所有值,包括空字符串,但不包括 NULL

然而,这里需要注意的是,LIKE 操作符并不会返回字段值为 NULL 的行。当列的值是 NULL 时,LIKE 操作符会返回 UNKNOWN,这就像其他的比较操作一样,因为 NULL 表示未知或缺失的值。

如果查询返回了包含 Name 为 NULL 的数据,那可能是因为你的查询中有其他的 JOIN 或 WHERE 条件允许这些行被返回。例如,如果你使用了左连接(LEFT JOIN),那么即使连接的条件不成立,主表中的行也会被返回,并且连接表中的列会显示为 NULL

如果你的意图是为了在Name字段可能包含NULL值的情况下,也能够正确地执行模糊匹配,那么你可能需要在 WHERE 子句中显式地处理这种情况,例如:

ISNULL(Name, ‘’) LIKE ‘%’+@Name+’%'

ISNULL函数的作用是,如果GysNameNULL,则将其替换为一个空字符串'',这样即使NameNULLLIKE子句也能够执行,因为空字符串与任何模式匹配都是有效的。 

例如,如果@Name的值是'ABC',那么ISNULL(Name, '') LIKE '%'+@Name+'%'会变成:

        如果Name是NULL,则变为'' LIKE '%ABC%',这通常是FALSE(除非@Name也是空字符串)。
        如果Name是非NULL值,比如'XYZABC',则变为'XYZABC' LIKE '%ABC%',这是TRUE。

INT 类型的字段和字符串类型的字段在 SQL 中的匹配规差异主要体现在以下几点:

  1. 比较运算符

    • 对于 INT 类型的字段,通常使用的比较运算符包括 =!=<><=>= 等。
    • 对于字符串类型的字段,除了上述比较运算符,还经常使用 LIKE 运算符进行模糊匹配。LIKE 运算符可以与通配符 %(匹配任意字符序列)和 _(匹配任意单个字符)一起使用。
  2. NULL 值的处理

    • 当 INT 类型字段比较时,如果字段值为 NULL,则任何与 NULL 的比较都会返回 NULL,这在布尔上下文中被视为 FALSE,不满足 WHERE 子句的条件。
    • 当字符串字段使用 LIKE 进行模糊匹配时,如果字段值为 NULL,同样任何与 NULL 的比较都会返回 NULL。但是,如果比较的字符串是空字符串 '',则 % 会匹配空字符串,因此 LIKE '%' 会匹配所有非 NULL 字符串值。
  3. 空字符串与 NULL

    • 在 INT 类型字段中,不存在空字符串的概念,字段要么有具体的整数值,要么是 NULL
    • 在字符串类型字段中,空字符串 '' 和 NULL 是不同的。空字符串是一个有效的值,表示没有字符,而 NULL 表示值未知或缺失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值