使 LEAST() 函数返回一个非空值

Posted

技术标签:

【中文标题】使 LEAST() 函数返回一个非空值【英文标题】:Make LEAST() function return a non-empty value 【发布时间】:2018-07-12 17:41:20 【问题描述】:

我有 5 列日期(col1、col2、col3、col4、col5),其中一些是空的或带有 null。 我需要从所有这些列中找到一个最小日期。

我正在使用“最少”功能,它工作正常,但如果我有一列有日期而其他列是空的,“最少”将返回给我空字段!

如何跳过空字段或空列,只返回日期!或者我需要在使用最少功能之前检查每一列是否为空! 谢谢!

select id, least(vi_date1, vi_date2,vi_date3,vi_date4,vi_date5) as "Min Date", vi_date1, vi_date2,vi_date3,vi_date4,vi_date5 from table

【问题讨论】:

LEAST 不能直接用于具有NULL 值的表。因为当列值为NULLLEAST 返回NULL 好的,我明白了,空列呢!??我可以将所有 null 替换为空! 我会将空值和 NULL 值转换为日期格式9999-12-31,类似于IF(vi_date1 = '' OR vi_date1 IS NULL, '9999-12-31', vi_date1) 感谢您的回答,但我的任务是在所有 5 个日期列中找到最大值和最小值,对于最大结果,它将不起作用! 定义“空”。那些日期/日期时间列还是 varchars? 【参考方案1】:

只需使用IF(col <> '', col, '...') 将 NULL 和空字符串转换为大(或小)值,然后使用 LEAST(或 GREATEST)函数:

SELECT
    NULLIF(LEAST(
        IF(vi_date1 <> '', vi_date1, '9999-12-31'),
        IF(vi_date2 <> '', vi_date2, '9999-12-31'),
        IF(vi_date3 <> '', vi_date3, '9999-12-31'),
        IF(vi_date4 <> '', vi_date4, '9999-12-31'),
        IF(vi_date5 <> '', vi_date5, '9999-12-31')
    ),'9999-12-31') AS Min_Date,
    NULLIF(GREATEST(
        IF(vi_date1 <> '', vi_date1, '1000-01-01'),
        IF(vi_date2 <> '', vi_date2, '1000-01-01'),
        IF(vi_date3 <> '', vi_date3, '1000-01-01'),
        IF(vi_date4 <> '', vi_date4, '1000-01-01'),
        IF(vi_date5 <> '', vi_date5, '1000-01-01')
    ),'1000-01-01') AS Max_Date,
    vi_date1,
    vi_date2,
    vi_date3,
    vi_date4,
    vi_date5
FROM testdata

DB Fiddle

【讨论】:

由于某种原因这不起作用,但是当我删除 NULLIF,'1000-01-01') 时它起作用了。如果条件为 null 或大于now,还有什么方法可以设置条件?【参考方案2】:

使用COALESCE 函数忽略NULL

更新 - 包括最小和最大日期 - 同时检查空日期或空日期

  select Id, least(COALESCE(IFNULL(vi_date1,''), '9999-12-31 23:59:59') , 
                   COALESCE(IFNULL(vi_date2,''),'9999-12-31 23:59:59'),
                   COALESCE(IFNULL(vi_date3,''),'9999-12-31 23:59:59'),
                   COALESCE(IFNULL(vi_date4,''),'9999-12-31 23:59:59'),
                   COALESCE(IFNULL(vi_date5,''),'9999-12-31 23:59:59')) as "Min Date", 
          , GREATEST(COALESCE(IFNULL(vi_date1,''), '1000-01-01 00:00:00') , 
                   COALESCE(IFNULL(vi_date2,''),'1000-01-01 00:00:00'),
                   COALESCE(IFNULL(vi_date3,''),'1000-01-01 00:00:00'),
                   COALESCE(IFNULL(vi_date4,''),'1000-01-01 00:00:00'),
                   COALESCE(IFNULL(vi_date5,''),'1000-01-01 00:00:00')) as "Max Date", 
          vi_date1, vi_date2,vi_date3,vi_date4,vi_date5 
          vi_date1, vi_date2,vi_date3,vi_date4,vi_date5 
 from table

【讨论】:

错误的函数嵌套.. LEAST 仍然会首先返回 NULL 值.. 这也不起作用 COALESCE 将返回第一个非 NULL 值,这意味着一个值进入 LEAST 函数。 我不知道,但这个解决方案对我不起作用!此查询仅返回包含所有 5 列日期的行。

以上是关于使 LEAST() 函数返回一个非空值的主要内容,如果未能解决你的问题,请参考以下文章

如何忽略 PostgreSQL 窗口函数中的空值?或返回列中的下一个非空值

返回第一个非空值

Mysql - 转换非空值第 2 部分

ORACLE 内置函数之GREATEST和LEAST

如何在 Java 中获取第一个非空值?

COALESCE函数