我正在比较两个日期,并试图确定两个日期的最大值。空日期将被视为小于有效日期。我正在使用以下案例陈述,它有效 - 但感觉非常低效和笨重。还有更好的方法吗?
update @TEMP_EARNED
set nextearn = case when lastoccurrence is null and lastearned is null then null
when lastoccurrence is null then lastearned
when lastearned is null then lastoccurrence
when lastoccurrence > lastearned then lastoccurrence
else lastearned end;
(这是在MS SQL 2000,FYI。)
答案 0 :(得分:6)
select c1, c2,
case when c1 > c2 then c1 else coalesce(c2,c1) end as max
from twocol;
+------+------+------+
| c1 | c2 | max |
+------+------+------+
| NULL | NULL | NULL |
| NULL | 2 | 2 |
| 1 | NULL | 1 |
| 1 | 2 | 2 |
| NULL | NULL | NULL |
| 2 | NULL | 2 |
| NULL | 1 | 1 |
| 2 | 1 | 2 |
+------+------+------+
为什么这样做?如果两个操作数都不为null,那么我们得到一个“正常”的比较:当c1>时,“then”分支。 c2,当c1< = c2时的else分支。
在“else”分支上,我们调用coalesce,但由于它的第一个参数是非null c2,我们返回c2。
。
但是如果任一操作数为null,则测试c1 > c2
的计算结果为false,并返回coalesce( c2, c1 )
。
如果空操作数是c1,我们得到c2,这是我们想要的,因为我们(对于这个问题)调用null是“小于”任何非空值。
如果空操作数是c2,我们得到c1。这很好,因为c1要么不为空,因此(对于这个问题)“大于”空c2, 或...
如果两个操作数都为null,我们得到c1,但是我们得到的并不重要,因为两者都是null。
另一个优点是,这个成语适用于
operator >
无效的任何类型,无需进一步考虑或详细说明。
答案 1 :(得分:4)
SQL Server可以存储在日期时间字段中的最早日期是1753年1月1日,因此如果您只计算该日期的空值,那么您可以在一行中执行此操作:
set nextearn = case when coalesce(lastoccurrence, '1753-01-01 00:00') > coalesce(lastearned, '1753-01-01 00:00') then lastoccurrence else lastearned end;
如果你的字段是smalldatetime,那么最小值是1900年1月1日,所以它将是:
set nextearn = case when coalesce(lastoccurrence, '1900-01-01 00:00') > coalesce(lastearned, '1900-01-01 00:00') then lastoccurrence else lastearned end;
答案 2 :(得分:1)
试试这个:
Set nextearn = Case When IsNull(lastoccurrence, 0) > IsNull(lastearned , 0)
Then lastoccurrence Else lastearned End
sql server中的所有日期都存储为两个整数,opne表示日期(自1900年1月1日以来的天数),另一个表示时间(秒数[SmallDatetime]或milleseconds [DateTime]自午夜以来) ......
这两个数字组合为Integer.DecimalFraction(DateInteger.TimePortion)。 因此,数字0.0代表1900年1月1日午夜,2.5代表1900年1月3日中午等......
使用表达式中的数字,无需将字符串表示形式解析为数字,然后将其与表示其他日期的数字进行比较...