zoukankan      html  css  js  c++  java
  • 数据值为NULL,导致条件查询不到正确结果,ISNULL函数的使用解决问题

        我在做一个需求是这样的:联查多张表,并且更据条件返回数据。

        但是,根据我的WHERE条件获取到的数据总是不正确,通过反复的研究,发现了问题的所在:

        某些列的值为NULL,在把这些列作为条件时,就会匹配不到正确的值,故而返回不正确的数据。

        示例:

        数据表(Users)及数据如下:

       image

        需求:查询所有数据中,Name不是以’L’开头并且Mobile中不包含’186’ 的数据   

        SQL语句:

    SELECT 
    	* 
    FROM 
    	dbo.Users 
    WHERE 
    	[Name] NOT LIKE 'L%' AND 
    	Mobile NOT LIKE '%186%'


        查询结果如下:

        image

      奇怪,为什么获取不到数据呢?实际应该返回ID等于4和5的数据才对的。

       image

    于是,我思考了起来。。。。。。。。。思考中。。。。。。。。。

    突然,眼前一亮,请注意:数据列中为NULL的地方 , 是的,没错问题就处在这里。

    那么什么是NULL值呢???

    NULL表示值为空,为空就是说该字段还没有经行任何的赋值操作,它的值是未知的,所以我们无法拿它与其他类型的值经行比较,如果用它去和其他值比较的话,那么返回的一定是未知,这样,我们得到的数据就是不准确的数据了。

    说道NULL值,就一定得说一下什么是三值逻辑,在SQL中有逻辑运算和比较运算,他们的取值一般有两种:True和False ,但是在表达式中涉及到NULL值的时候,取值就会是第三种,即UNKNOWN

    关于UNKNOWN的相关知识点整理如下:
    1、NOT  TRUE 等于 FALSE,,NOT  FALSE 等于 TRUE,,否定的UNKNOWN还是UNKNOWN;
    2、比较两个NULL值,将返回FALSE而不是UNKOWN;
    3、所有的查询筛选器(ON、WHERE和HAVING)都会把UNKNOWN当作FALSE处理,UNKNOWN的行会被排除在结果集之外;
    4、CHECK约束中的UNKNOWN被当作TRUE来处理,假设表中包含一个CHECK约束,要求salary列的值必须大于0,向该表插入salary为NULL的行时可以被接受;
    5、如果表中有一列定义了UNIQUE约束,将无法向表中插入两行该列值为NULL的数据;
    6、GROUP BY会把所有NULL值分组到一起;ORDER BY 会把所有的NULL值排列在一起;
    7、NULL值在聚合函数里的使用有点意思:Count(*)会返回表中的所有行,Count(salary)将会排除掉salary为NULL的行;
         使用AVG(salary)求平均值时也会排除掉salary为NULL的行,这样可能会导致计算的平均值不准确,需要将NULL转换成0或其它默认值再参与计算;
         在数据库设计时,关键字段上应考虑设计默认值,防止在统计时出现误差;

    (摘自:http://www.cnblogs.com/Yuanet/archive/2011/03/17/1986808.html ,我是看了这些才学习到三值逻辑的 :) )

    好了,先说到这儿,继续处理需求,怎么避免NULL值呢???

    很简单,既然NULL值无法和其他值进行比较,那么,我们就先对它进行转换,让它和要比较的值类型一致,这样就可以了。这里,我们使用ISNULL函数来完成转换。

    先说一下ISNULL函数的语法

    ISNULL ( check_expression , replacement_value )
    check_expression
    :将被检查是否为 NULL 的表达式。 check_expression 可以为任何类型。
    replacement_value:当 check_expression 为 NULL 时要返回的表达式。 replacement_value 必须是可以隐式转换为 check_expresssion 类型的类型。

    ISNULL函数的返回类型:如果文字 NULL 作为 check_expression 提供,则返回 replacement_value 的数据类型。 如果文字 NULL 作为 check_expression 提供并且未提供 replacement_value,则返回 int。

    (具体ISNULL的相关信息,参见MSDN:http://msdn.microsoft.com/zh-cn/library/ms184325.aspx)

    好了,来看看用ISNULL处理过的T-SQL语句吧:

    SELECT 
    	* 
    FROM 
    	dbo.Users 
    WHERE 
    	ISNULL([Name],'') NOT LIKE 'L%' AND 
    	ISNULL(Mobile,'') NOT LIKE '%186%'

    执行结果如下:

    image

    OK,这回,得到了我们想要的结果,问题解决了。

     作者: 期星揽月——每天进步一点点……

     出处:http://qixing_gan.cnblogs.com/

     版权:本文版权归作者和博客园共有,欢迎转载,但必须保留作者版权,并给出原文链接,谢谢合作!

    与我在线交流

  • 相关阅读:
    c语言面试
    汇编面试基础
    求余符号的用法
    ++a和a++的一点不同
    OVER子句
    SQL执行计划解析(1) 执行计划基础
    sql 排序规则 chinese_prc_ci_as
    SQL执行计划解析(2) 基本查询的图形执行计划
    过sql_trace跟踪得到了该SQL的执行计划,如何看懂执行计划
    JS日历控件集合附效果图、源代码
  • 原文地址:https://www.cnblogs.com/qixing_gan/p/3012770.html
Copyright © 2011-2022 走看看