MySQL: 获取多列的 MAX 或 GREATEST,但使用 NULL 字段

我试图在每个记录(MySQL)的三个不同字段中选择最大日期 因此,在每一行中,date1、 date2和 date3: date1始终是填充的,date2和 date3可以为 NULL 或空 GREATEST 语句简单明了,但是对 NULL 字段没有影响,因此这个语句不能很好地工作:

SELECT id, GREATEST(date1, date2, date3) as datemax FROM mytable

我还尝试了一些更复杂的解决方案,比如:

SELECT
CASE
WHEN date1 >= date2 AND date1 >= date3 THEN date1
WHEN date2 >= date1 AND date2 >= date3 THEN date2
WHEN date3 >= date1 AND date3 >= date2 THEN date3
ELSE                                        date1
END AS MostRecentDate

这里也有同样的问题: 返回正确的记录时,NULL 值是一个很大的问题

拜托,你有解决办法吗? 先谢谢你。

43783 次浏览

GREATEST中使用日期列之前,请先将日期列设置为。

你处理他们的方式将取决于你想如何处理 NULL. . 或高或低?

使用 COALESCE

SELECT id,
GREATEST(date1,
COALESCE(date2, 0),
COALESCE(date3, 0)) as datemax
FROM mytable

更新: 这个答案之前使用的是 IFNULL,它确实有用,但是正如 Mike Chamberlain 在评论中指出的,COALESCE实际上是首选的方法。

如果 date1永远不可能是 NULL,那么结果就永远不应该是 NULL,对吗?然后你可以使用这个,如果你想 NULL日期不计算在计算中(或者改变 1000-01-019999-12-31,如果你想 Null 计算为“时间结束”) :

GREATEST( date1
, COALESCE(date2, '1000-01-01')
, COALESCE(date3, '1000-01-01')
) AS datemax

但是,如果所有的日期都是空的呢?您仍然希望将 null 作为输出,对吗?那你需要这个

select nullif(greatest(coalesce(<DATEA>, from_unixtime(0)), coalesce(<DATEB>, from_unixtime(0))), from_unixtime(0));

现在,如果两个都为空,你就会得到 null,如果其中一个不为空,两个都不为空,你就会得到最大值。

这太疯狂了,特别是如果你要多次使用它,那么你可能想要创建一个函数,像这样:

delimiter //
drop function if exists cp_greatest_date//
create function cp_greatest_date ( dateA timestamp, dateB timestamp ) returns timestamp
deterministic reads sql data
begin


# if both are null you get null, if one of them is not null of both of them are not null, you get the greatest
set @output = nullif(greatest(coalesce(dateA, from_unixtime(0)), coalesce(dateB, from_unixtime(0))), from_unixtime(0));
# santiago arizti


return @output;
end //
delimiter ;

然后你可以像这样使用它

select cp_greatest_date(current_timestamp, null);
-- output is 2017-05-05 20:22:45