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)
根据您的小提琴,这将返回您在所有条件下指定的确切结果.
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)
使用 IsNull
SELECT recordid, MIN(startdate), MAX(IsNull(enddate, Getdate()))
FROM tmp
GROUP BY recordid
Run Code Online (Sandbox Code Playgroud)
我已将第二条指令中的 MIN 修改为 MAX
| 归档时间: |
|
| 查看次数: |
86212 次 |
| 最近记录: |