如何在MIN或MAX中包含空值?

Ant*_*ift 59 sql t-sql sql-server

我有一个表,我正在存储时间跨度数据.该表的架构类似于:

ID INT NOT NULL IDENTITY(1,1)   
RecordID INT NOT NULL  
StartDate DATE NOT NULL  
EndDate DATE NULL  
Run Code Online (Sandbox Code Playgroud)

我正在尝试计算每个记录ID的开始和结束日期,因此最小StartDate和最大EndDate.StartDate不可空,所以我不需要担心这个,但我需要MAX(EndDate)来表示这是一个正在运行的时间跨度.

保持EndDate的NULL值并将其视为最大值非常重要.

最简单的尝试(下面)无法突出显示MIN和MAX将忽略NULLS的问题(来源:http://technet.microsoft.com/en-us/library/ms179916.aspx).

SELECT recordid, MIN(startdate), MAX(enddate) FROM tmp GROUP BY recordid
Run Code Online (Sandbox Code Playgroud)

我已经创建了一个基本设置完成的SQL小提琴.

http://sqlfiddle.com/#!3/b0a75

如何根据我的意愿弯曲SQL Server 2008以从SQLFiddle中给出的数据产生以下结果?

RecordId  Start       End  
1         2009-06-19  NULL
2         2012-05-06  NULL
3         2013-01-25  NULL
4         2004-05-06  2009-12-01
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 66

这有点难看,但因为NULLs对你有特殊的意义,这是我能想到的最干净的方法:

SELECT recordid, MIN(startdate),
   CASE WHEN MAX(CASE WHEN enddate IS NULL THEN 1 ELSE 0 END) = 0
        THEN MAX(enddate)
   END
FROM tmp GROUP BY recordid
Run Code Online (Sandbox Code Playgroud)

也就是说,如果任何一行有一个NULL,我们想强迫它成为答案.只有当没有行包含a时NULL,我们才会返回MIN(或MAX).


Mat*_*win 41

您想要的效果是将NULL视为最大可能日期,然后在完成时再次将其替换为NULL:

SELECT RecordId, MIN(StartDate), NULLIF(MAX(COALESCE(EndDate,'9999-12-31')),'9999-12-31') 
  FROM tmp GROUP BY RecordId
Run Code Online (Sandbox Code Playgroud)

根据您的小提琴,这将返回您在所有条件下指定的确切结果.

  • 请注意,在8000年后,我们需要查看此代码...但是,比接受的答案要清晰得多. (11认同)
  • 这比IMO接受的答案更清晰.我使用了一个小的变化:`NULLIF(MAX(COALESCE(EndDate,'infinity':: timestamp)),'infinity':: timestamp)` (6认同)

t-c*_*.dk 18

在我的表达式中 - count(enddate)计算enddates不为null的行数(*)计算总行数通过比较,您可以轻松判断是否有任何enddates包含null.如果它们相同则结果是max(enddate).否则,该情况将默认返回null,这也是答案.这是一种非常流行的方式来进行这种精确检查.

SELECT recordid, 
MIN(startdate), 
case when count(enddate) = count(*) then max(enddate) end
FROM tmp 
GROUP BY recordid
Run Code Online (Sandbox Code Playgroud)


Mar*_*čič 8

使用 IsNull

SELECT recordid, MIN(startdate), MAX(IsNull(enddate, Getdate()))
FROM tmp 
GROUP BY recordid
Run Code Online (Sandbox Code Playgroud)

我已将第二条指令中的 MIN 修改为 MAX

  • 甚至更好,**Coalesce**,它与 ansi-sql 兼容 (10认同)
  • 不幸的是,我需要将 null 保持为高值。我已经编辑了我的问题以更清楚地说明这一点。 (2认同)