我有这个架构
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操作消除空值
为什么以及我该怎么办呢?
答案 0 :(得分:89)
你也无能为力。
这只是一条信息性消息required in the SQL standard。它没有任何不良影响。
返回此消息的原因是SQL空间中的大多数操作都会传播。
SELECT NULL + 3 + 7
返回NULL
(关于NULL
作为未知数量,这是有道理的,因为? + 3 + 7
也是未知的)
但
SELECT SUM(N)
FROM (VALUES (NULL),
(3),
(7)) V(N)
返回10
以及忽略空值的警告。
然而,对于典型的聚合查询,这些正是您想要的语义。否则,单个NULL
的存在将意味着所有行上该列的聚合总是会产生NULL
,这不是非常有用。
下面最重的蛋糕是什么?(Image Source,Creative Commons我的图像被修改(裁剪和注释)
在第三个蛋糕称重后,鳞片破裂,因此没有关于第四个蛋糕的信息,但仍然可以测量周长。
+--------+--------+---------------+
| 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,并且警告只会提醒您发生这种情况。
答案 1 :(得分:4)
@juergen提供了两个好的答案:
SET ANSI_WARNINGS OFF
select @mindate = min(isnull(d, cast(0 as datetime))) from t
但是,如果要忽略d列为空的行并且不关心ANSI_WARNINGS
选项,则可以通过排除d设置为null的所有行来执行此操作:
select @mindate = min(d) from t where (d IS NOT NULL)
答案 2 :(得分:3)
答案 3 :(得分: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
答案 4 :(得分:1)
如果您想让聚合考虑null
值并将结果视为null
,您可以使用:
SELECT IIF(COUNT(N) != COUNT(*), NULL, SUM(N)) as [Sum]
FROM (VALUES (NULL),
(3),
(7)) V(N)
如果没有给出所有值,则返回null
。