收到警告:空值被聚合或其他 SET 操作消除了

问题描述 投票:0回答:5

我有这个架构

create table t(id int, d date) 

insert into t (id, d) values (1, getdate()), 
                             (2, NULL)

做的时候

declare @mindate date    
select @mindate = min(d) from t

我收到警告

通过聚合或其他 SET 操作消除空值

为什么以及我能做什么?

sql sql-server settings
5个回答
134
投票

大多数情况下你不应该采取任何措施。

  • 可以通过设置
    ansi_warnings
    关闭来禁用警告,但这会产生 其他影响,例如关于如何处理除零的问题,当您的查询使用索引视图、计算列或 XML 方法等功能时,可能会导致失败。
  • 在某些有限的情况下,您可以重写聚合以避免它。例如
    COUNT(nullable_column)
    可以重写为
    SUM(CASE WHEN nullable_column IS NULL THEN 0 ELSE 1 END)
    但这并不总是可以在不改变语义的情况下直接完成。

这只是一条信息性消息SQL 标准所要求的。除了向消息流添加不需要的噪音之外,它没有任何不良影响(除了意味着 SQL Server 不能绕过读取

NULL
行,这可能会产生开销,但禁用警告并不能提供更好的执行计划在这方面)

返回此消息的原因是在 SQL 中的大多数操作中传播空值。

SELECT NULL + 3 + 7
返回
NULL
(将
NULL
作为未知量,这是有道理的,因为
? + 3 + 7
也是未知的)

但是

SELECT SUM(N)
FROM   (VALUES (NULL),
               (3),
               (7)) V(N) 

返回

10
并警告空值被忽略。

然而,对于典型的聚合查询,这些“正是您想要的语义”。否则,单个 NULL 的存在意味着该列上所有行的聚合最终总是会产生

NULL
,这不是很有用。

下面哪个蛋糕最重?

图像来源知识共享图像由我修改(裁剪和注释))

第三个蛋糕称重后,秤破裂了,因此没有关于第四个蛋糕的信息,但仍然可以测量周长。

+--------+--------+---------------+ | CakeId | Weight | Circumference | +--------+--------+---------------+ | 1 | 50 | 12.0 | | 2 | 80 | 14.2 | | 3 | 70 | 13.7 | | 4 | NULL | 13.4 | +--------+--------+---------------+

查询

SELECT MAX(Weight) AS MaxWeight, AVG(Circumference) AS AvgCircumference FROM Cakes

退货

+-----------+------------------+ | MaxWeight | AvgCircumference | +-----------+------------------+ | 80 | 13.325 | +-----------+------------------+

尽管从技术上讲不可能确定 80 是最重蛋糕的重量(因为未知数可能更大),但上面的结果通常比简单地返回未知数更有用。

+-----------+------------------+ | MaxWeight | AvgCircumference | +-----------+------------------+ | ? | 13.325 | +-----------+------------------+

您可能希望忽略 NULL,而警告只是提醒您这种情况正在发生。


4
投票

使用
    SET ANSI_WARNINGS OFF
  •  抑制警告
    
    假设您想包含 NULL 值并将它们视为(例如)使用
  • select @mindate = min(isnull(d, cast(0 as datetime))) from t
  • 
    
    
  • 但是,如果您想忽略 d 列为 null 的行并且不关心
ANSI_WARNINGS

选项,那么您可以通过排除 d 设置为 null 的所有行来实现此目的:


select @mindate = min(d) from t where (d IS NOT NULL)



2
投票
MIN

函数。


“除了 COUNT 之外,聚合函数忽略空值” 请参阅

聚合函数 (Transact-SQL)


2
投票
min()

应返回什么作为

d
的最小值?

该错误通知您

min()

函数未考虑

null
的记录。

因此,如果它应该忽略

NULL

值并返回最低的

现有
日期,那么您可以忽略此警告。 如果您也想抑制此单个语句的警告,那么您可以这样做

set ansi_warnings off select @mindate = min(d) from t set ansi_warnings on

如果您希望通过使用默认值来考虑 
NULL

值,那么您可以像这样设置默认日期值


select @mindate = min(isnull(d, cast(0 as datetime))) from t



2
投票
null

值并将结果视为

null
,您可以使用:

SELECT IIF(COUNT(N) != COUNT(*), NULL, SUM(N)) as [Sum] FROM (VALUES (NULL), (3), (7)) V(N)

如果未给出所有值,则返回 
null

    

© www.soinside.com 2019 - 2024. All rights reserved.