Sql 获取警告:通过聚合或其他集合操作消除空值
我有这个模式Sql 获取警告:通过聚合或其他集合操作消除空值,sql,sql-server,Sql,Sql Server,我有这个模式 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 我得到了警告 通过聚合或其他集合操作消除空值 为什么以及我能做些什么?在您的情况下,min()应该以d的最低值返回什么 该错
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
我得到了警告
通过聚合或其他集合操作消除空值
为什么以及我能做些什么?在您的情况下,min()
应该以d
的最低值返回什么
该错误通知您min()
函数未考虑null
记录
因此,如果它应该忽略NULL
值并返回现有的最低日期,那么您可以忽略此警告
如果您还希望抑制此单个语句的警告,则可以这样做
set ansi_warnings off
select @mindate = min(d) from t
set ansi_warnings on
select @mindate = min(isnull(d, cast(0 as datetime)))
from t
如果希望通过使用默认值来考虑NULL
值,则可以像这样设置默认日期值
set ansi_warnings off
select @mindate = min(d) from t
set ansi_warnings on
select @mindate = min(isnull(d, cast(0 as datetime)))
from t
大多数情况下,你不应该对此采取任何行动
- 可以通过关闭
来禁用警告,但当查询使用索引视图、计算列或XML方法等功能时,这会导致失败ansi_warnings
- 在某些有限的情况下,您可以重写聚合以避免它。e、 g.
可以重写为COUNT(nullable\u column)
,但如果不更改语义,这并不总是可以直接执行SUM(当nullable\u column为NULL时,则为0,否则为1结束)
NULL
行,这可能会导致错误,但禁用警告不会在这方面提供更好的执行计划)
返回此消息的原因是,在SQL nulls中的大多数操作中都会传播此消息
SELECT NULL+3+7
返回NULL
(将NULL
视为一个未知量,这是有意义的,因为?+3+7
也是未知的)
但是
返回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 |
+-----------+------------------+
因此,您很可能希望忽略空值,而警告只是提醒您发生这种情况。我认为您可以在这种情况下忽略此警告,因为您使用了
MIN
功能
“除计数外,聚合函数忽略空值”
请参阅@juergen提供了两个很好的答案:
- 使用
SET ANSI\u WARNINGS OFF
- 假设您希望包括空值,并将它们视为(比如)使用
select@mindate=min(isnull(d,cast(0为datetime)),从t
ANSI_WARNINGS
选项,则可以通过排除d设置为null的所有行来完成此操作,如下所示:
select @mindate = min(d) from t where (d IS NOT NULL)
如果要聚合,请考虑<代码> null <代码>值,并将结果作为<代码> null >,可以使用:
SELECT IIF(COUNT(N) != COUNT(*), NULL, SUM(N)) as [Sum]
FROM (VALUES (NULL),
(3),
(7)) V(N)
如果未给出所有值,则返回
null
。建议的“修复”将返回不正确的结果。它将表明最早的日期是1900-01-01
(除非数据中的日期恰好早于该日期),如果d
具有这两个值,如“1/1/2001”和“1/1/2012”,将会发生什么情况。这将返回“1/1/1900”作为最小值?因此,如果执行select*from table where date>@mindate
,这将导致添加时出现问题,其中d不为null
我收到了相同的警告。我不介意警告本身,但是,我需要SQL代理运行存储过程,当我这样做时,警告会导致代理作业失败。@Richie它不会使SQL代理作业失败。它将出现在作业历史记录中可见的输出中,当作业因其他原因失败时,您可能会看到该输出,因此假设原因是您的选项1具有其他副作用。选项3仅在单个聚合列的情况下有效。对于选择min(d1),min(d2)
没有可用于执行此操作的where子句。你为什么关心这个消息?这只是信息。谢谢马丁。我的前两个选项只是总结了juergen之前的答案,以便形成一个平台,在此平台上介绍我的选项(3?)。是的,我的建议只有在选择的汇总(最小、最大、平均、总和等)列作为问题的OP时才有效。该消息可能只是信息性的,但当我看到它们时,它们总是让我质疑查询,这打破了我在手头工作中的注意力。这很好地解释了问题,并允许我愉快地继续忽略警告,因为这正是我所期望的。尽管我对多个服务器上的空传播感到恼火有时候,我想我从来没有真正质疑过背后的原因。任何能让我“呼呼”或涉及饼干的答案都得到了我的投票。我可能已经在谷歌上搜索了好几次这个错误,但这是迄今为止对这个问题的最好解释,以及它为什么会出现,以及什么时候重要。非常感谢。很好的解释!