NULL值的一些知识

SELECT count(base_uom) as 'my_column' , base_uom
FROM schema.table
group by base_uom
order by 'my_column'

想对表schema.table里的base_uom字段做统计分析,就是想看看这字段里的某个值出现了几次,
由于这字段里有NULL值,统计的时候SQLServer是不分析的,
就是说不管这字段里NULL出现了几次,count出来总是0
结果:
-----------------------
my_column base_uom
----------- ----------
[color=red]0 NULL[/color]
1 %
1 CAN
-----------------------

用这个方法就可以了:
SELECT count(isnull(base_uom,'')) as 'my_column' , base_uom
FROM schema.table
group by base_uom
order by 'my_column'

结果:
my_column base_uom
----------- ----------
1 %
1 CAN
14 UNIT
[color=red]22 NULL[/color]
23 STR
25 G
30 PRS
34 TN

说明:
count(isnull(base_uom,''))
这个用了个函数,其实第二个参数''无所谓了,随便什么,只要不是NULL,让其参加统计就可以了

-----------------下面的文字是转其他人的,参考参考------
NULL值的三大特点,分别是:1)NULL值不参加统计;2)NULL值不进入计算表达式;3)不能与其它值进行比较。
所谓NULL值不参加统计 即 在使用统计函数时,凡是涉及到 NULL值的都会被忽视掉(用词可能不准确),不要以为这不重要,其实在某些地方这是很重要的。
而 NULL值不进入计算也就是说在进行数据之间的统计计算时,若有为 NULL值的项,那么它是不进入即不参加计算的。这也是一个不容忽视的问题。这即使在生活中也是常见的。
就好比如说一个人的奖金为NULL值(没有录入数据或其它的原因,不做探讨),而他的基本工资总不会为 0 吧?!(如果为0,早就被T了),月末算总工资的时候把基本工资加上奖金,
而若是奖金为 NULL值,总工资 = 基本工资 + 奖金(NULL),那么当此种情况发生时,总工资 = 基本工资 ?
肯定的回答是:不等于。因为奖金为 NULL值,NULL值代表具体的什么值?都不知道。而不知道NULL值到底是多少,那么又怎么能进行计算呢?所以总工资等于 NULL 的,也是不确定的。这样,还有员工敢在公司吗?万一你来个总工资的 NULL 为真的空了,那还做什么工作啊?!这就涉及到一个强制转换的问题,即把 NULL值强制转换为 0 ,让其具备业务意义。而强制转换的关键字就是 IS ,语法即 IS NULL;这样就可以进行涉及 NULL值的计算了。
不过 NULL值也不是对所有的统计函数都有影响。一般来说。统计平均值(AVG)时, NULL值是一定会有影响的;统计最小值(MIN)时, NULL值是可能会对 MIN 有影响,在我认为是有点随机性质;统计最大值(MAX)或统计和(NULL)时,NULL值是对其完全没有影响的。
所以又有一种说法是:null值不参加统计,不参加计算,只能用is判断。
判断Null值语句:select * from 表 where 字段 is null;
转换null值语句:select 字段1,字段2,字段3,is null(字段3,’某个值’) from 表;
总之,我们要认真对待 NULL值,最好在使用统计函数时,都加上 IS NULL,以防意外出现。
还有有关强制转换的关键字:cast ,convert。

关于舍入,示例:
select ceiling(10.1),ceiling(10.9); --结果: 11
select floor(10.1),floor(10.9); --结果: 10
select ceiling(-10.1),ceiling(-10.9); --结果: -10
select floor(-10.1),floor(-10.9); --结果: -11
<think>好的,我现在需要回答用户关于SQL中NULL在表关联时的发生情景及影响的问题。用户已经提供了之前的对话和一些参考资料,我需要仔细分析这些信息,并结合自己的知识来构建一个全面且准确的回答。 首先,用户的问题集中在NULL在表关联时的发生情景和影响。根据之前的对话,用户可能已经了解笛卡尔积的概念,现在想深入探讨NULL在连接操作中的行为。我需要确保回答覆盖以下几个方面: 1. **NULL在连接条件中的处理方式**:不同数据库对NULL的处理可能不同,但通常NULL与任何的比较结果都是未知(UNKNOWN),导致这些行被排除在连接结果之外。 2. **具体发生情景**:比如在INNER JOIN、LEFT JOIN等不同类型的连接中,NULL如何影响结果集。 3. **实际影响**:比如数据丢失、查询结果不符合预期、性能问题等。 4. **解决方案和最佳实践**:如何避免或处理NULL带来的问题,例如使用COALESCE函数或调整查询逻辑。 接下来,我需要参考用户提供的引用内容,看看是否有相关的信息可以利用。例如,引用[1]提到在NOT IN子查询中出现NULL会导致整个查询没有结果,这说明NULL在子查询中的处理可能影响主查询的结果。引用[3]讨论了使用NOT EXISTS和NOT IN时的性能差异,这可能涉及到NULL处理的不同方式。引用[5]中的SQL查询使用了IFNULL函数来处理可能的NULL,这可以作为处理NULL的一个实例。 同时,用户之前的回答中提到了笛卡尔积的发生场景,但当前问题转向NULL,因此需要区分两者的不同。不过,可能需要提到在连接条件中使用NULL可能导致意外的笛卡尔积,但根据引用[4],更多是连接条件缺失导致的笛卡尔积,而非NULL本身。 接下来需要组织回答的结构,确保逻辑清晰,分点说明。可能需要分为发生情景和影响两部分,每个部分下再细分具体情况。同时,加入示例代码和解决方案部分,帮助用户更好地理解。 需要注意用户提供的引用中有提到不同数据库对NULL的处理可能不同,例如MySQL和SQLite在建表时的约束差异(引用[2]),但问题主要集中在查询时的关联操作,因此可能需要简要提及数据库差异,但主要关注通用情况。 另外,用户示例中的SQL语句(如引用[5])展示了如何处理NULL,这可以作为解决方案的一部分,例如使用IFNULL或COALESCE函数来替代NULL,确保连接条件有效。 最后,需要确保回答符合用户之前设定的格式要求:使用中文,行内公式用$...$,独立公式用$$...$$,代码块使用正确语法,并自然地添加引用标记。同时,生成相关问题,但根据用户指示,这次可能不需要,因为用户的问题已经明确。 总结思考步骤: 1. 确定用户的核心问题:NULL在表关联时的发生情景和影响。 2. 收集相关资料和引用内容,提取相关点。 3. 结构化回答,分情景和影响两部分,每部分细分具体情况。 4. 提供解决方案和最佳实践,引用示例中的处理方法。 5. 确保格式正确,引用标记适当,语言清晰。</think>#### SQL中NULL在表关联时的发生情景及影响 --- ### 一、NULL在表关联中的发生情景 #### 1. **连接条件包含可为空的字段** 当表关联的键(如`JOIN ON`子句中的字段)包含`NULL`时,可能导致匹配失败。 **示例**: ```sql SELECT * FROM employees e LEFT JOIN departments d ON e.department_id = d.id; ``` - 若`e.department_id`存在`NULL`,则这些记录无法与`d.id`匹配,但仍会保留在左连接结果中(`d`表字段为`NULL`)[^3]。 - 若`d.id`存在`NULL`,则右表无法匹配左表记录(除非左表字段也为`NULL`)。 #### 2. **使用`IN`或`NOT IN`子查询时子查询返回NULL** 在子查询中返回`NULL`会导致逻辑异常: - **`IN`子查询**:`NULL`不参与比较,结果不受影响。 - **`NOT IN`子查询**:若子查询结果包含`NULL`,则主查询会返回空结果集(因为`NOT IN (NULL)`等价于`!= NULL`,而`NULL`比较结果始终为`UNKNOWN`)[^1]。 **示例**: ```sql SELECT * FROM t WHERE t.col NOT IN (SELECT tt.col FROM tt); -- 若子查询返回NULL,则整个查询无结果 ``` #### 3. **外键关联中允许NULL** 若外键字段允许`NULL`,则关联时可能出现“未关联”的记录: ```sql SELECT * FROM orders o LEFT JOIN customers c ON o.customer_id = c.id; ``` - 若`o.customer_id`为`NULL`,则订单记录对应的客户信息字段均为`NULL`[^5]。 --- ### 二、NULL对表关联的影响 #### 1. **数据丢失或失真** - **内连接(`INNER JOIN`)**:若连接键为`NULL`,相关行会被完全排除在结果集外。 - **统计偏差**:聚合函数(如`COUNT`、`SUM`)可能因`NULL`导致统计结果不准确。例如,`COUNT(column)`会忽略`NULL`,而`COUNT(*)`不会。 #### 2. **逻辑错误风险** - **条件筛选失效**:`WHERE column = NULL` 永远返回假,正确写法应为 `WHERE column IS NULL`。 - **关联条件意外失效**:若连接键包含`NULL`,可能导致部分数据未被正确关联[^3]。 #### 3. **性能问题** - **索引失效**:大多数数据库的索引不包含`NULL`,若查询依赖`NULL`匹配,可能无法利用索引优化,导致全表扫描[^4]。 - **执行计划复杂化**:优化器可能因`NULL`的存在选择低效的执行路径。 --- ### 三、解决方案与最佳实践 #### 1. **显式处理NULL** - 使用`COALESCE`或`IFNULL`替换`NULL`: ```sql SELECT * FROM employees e LEFT JOIN departments d ON COALESCE(e.department_id, -1) = COALESCE(d.id, -1); -- 将NULL替换为默认-1,强制匹配 ``` #### 2. **避免子查询中的NULL污染** - 在子查询中排除`NULL`: ```sql SELECT * FROM t WHERE t.col NOT IN (SELECT tt.col FROM tt WHERE tt.col IS NOT NULL); ``` #### 3. **约束设计** - 若业务逻辑不允许空关联,应在表设计中为外键字段添加`NOT NULL`约束[^2]: ```sql ALTER TABLE orders MODIFY customer_id INT NOT NULL; ``` #### 4. **使用`NOT EXISTS`替代`NOT IN`** - `NOT EXISTS`对`NULL`更安全,且通常性能更优[^3]: ```sql SELECT * FROM test1 a WHERE NOT EXISTS (SELECT 1 FROM test2 b WHERE a.val = b.val); ``` --- ### 四、不同数据库的差异 - **MySQL**:允许外键字段为`NULL`,且不强制约束(除非显式定义`NOT NULL`)[^2]。 - **SQLite**:严格校验外键约束,建表时若引用无效字段会直接报错。 - **Oracle/SQL Server**:默认外键关联会忽略`NULL`,需通过触发器或约束额外控制。 --- ### 示例场景 **需求**:统计所有主管发展的用户数(包括直接发展和通过代理员间接发展)。 **处理NULL的SQL**: ```sql SELECT IFNULL(c.distri_user_id, c.user_id) AS userId, -- 代理员上级ID为空时,取自身ID COUNT(*) AS userCount FROM sys_user b JOIN sys_user c ON b.recommender_user_id = c.user_id WHERE c.distri_user_id IS NOT NULL OR c.new_flag = 30 GROUP BY userId ORDER BY userCount DESC LIMIT 30; ``` - **关键点**:`IFNULL`处理代理员与主管的层级关系,避免因`NULL`导致的分组错误[^5]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值