14

我想比较两列中的两个日期并获得最大值,然后与日期值进行比较。这两列也可以保存 NULL 值。

例如我想要下面的输出。

Col A         Col  B          OUTPUT
---------------------------------------
 NULL          NULL            NULL
 09/21/2013    01/02/2012      09/21/2013
 NULL          01/03/2013      01/03/2013 
 01/03/2013    NULL            01/03/2013 

我如何使用最大的功能或是否还有其他功能?我再次使用输出与另一个日期进行比较。

4

9 回答 9

27

您的问题具体涉及两列,但我遇到了需要GREATEST/LEAST两列以上的情况。在这些情况下,您可以使用COALESCE解决方案并将其扩展到所需的任意数量的列。

这是一个包含三列ab和的示例c

GREATEST(
    COALESCE(a, b, c),
    COALESCE(b, c, a),
    COALESCE(c, a, b)
)

请注意,列顺序的COALESCE更改使每个输入列COALESCE至少是第一个元素一次。唯一会返回 NULL 的情况是所有输入列都为 NULL。

在“通用解决方案”中,COALESCE语句的数量将等于输入列的数量:

GREATEST(
    COALESCE(col1, col2, col3, col4, ....),
    COALESCE(col2, col3, col4, ...., col1),
    COALESCE(col3, col4, ...., col1, col2),
    COALESCE(col4, ...., col1, col2, col3),
    COALESCE(...., col1, col2, col3, col4),
    ...
)
于 2016-08-29T16:25:24.793 回答
21

您可以尝试以下方法:

SELECT cola, colb, COALESCE( GREATEST( cola, colb ), cola, colb ) AS output
  FROM yourtable;

的原因COALESCE()是,如果其中一个参数是,则GREATEST()返回。NULLNULL

于 2016-02-08T03:00:49.277 回答
6

a case expression用于处理值的另一个版本null

select cola, colb, 
  case when cola is null and colb is null then null
    when cola is null then colb
    when colb is null then cola
    else greatest(cola, colb)
  end as output
from <table>;

COLA       COLB       OUTPUT   
---------- ---------- ----------

09/21/2013 01/02/2012 09/21/2013 
           01/03/2013 01/03/2013 
01/03/2013            01/03/2013 
于 2013-10-04T16:41:56.893 回答
4

在您的选择中使用 OracleCASE... WHEN结构:

SELECT COLA, COLB, CASE
  WHEN (COLA >= COLB OR COLB IS NULL)
    THEN COLA
  ELSE COLB
  END
  AS OUTPUT
FROM ...
于 2013-10-04T16:37:47.397 回答
4

您可以使用 NVL 函数消除任何列返回 NULL 的可能性。将任何 NULL 值替换为早于表中可能出现的任何日期的日期。

SELECT GREATEST(NVL(A,TO_DATE('01/01/1800','MM/DD/YYYY')), 
                NVL(B,TO_DATE('01/01/1800','MM/DD/YYYY'))) AS OUTPUT
FROM ...

然后,如果一个或多个列包含 NULL,GREATEST 函数将从提供的日期列表中返回最近的日期(最大日期),而不会无意中返回 NULL。

于 2018-03-14T10:47:08.240 回答
3

If you have many columns to compare (more than 2 or 3), then handling all the various CASE combinations might get unwieldy. You could try (11g):

with x as (
  select 1 as id, sysdate - 30 as col1, sysdate-50 as col2, sysdate-20 as col3,null as col4, sysdate-1 as col5 from dual
  union
  select 2 as id, sysdate - 10 as col1, sysdate-20 as col2, null as col3,null as col4, sysdate-35 as col5 from dual
  union
  select 3 as id, null as col1, null as col2, null as col3, null as col4, null as col5 from dual
)
select id, max(dates)
from x
UNPIVOT INCLUDE NULLS
(dates FOR colname IN (col1,col2,col3,col4,col5))
group by id
于 2013-10-04T18:17:30.240 回答
0

就像是

SELECT CASE WHEN ColA is NULL and ColB is NULL then NULL
WHEN coalesce(ColA, '01/01/1753')>coalesce(ColB, '01/01/1753') then ColA
ELSE ColB END as Output
于 2013-10-04T16:39:26.523 回答
0

我试过这个..谷歌搜索后发现

WITH ABC AS ( SELECT NULL AS col1 , NULL AS col2 FROM dual UNION
 SELECT NULL , DATE'2013-08-12' FROM dual UNION
  SELECT  DATE'2013-08-12' , NULL FROM dual UNION
   SELECT  DATE'2013-08-12',  DATE'2013-09-12' FROM dual)

   SELECT col1, col2 , substr(greatest('x'||col1,'x'||col2),2)
      FROM ABC;
于 2013-10-04T16:50:40.683 回答
0

使用 NVL 来解决这个问题,但是根据比较列的数量,共谋将增加:

select A.*, *greatest("COL A", "COL B") "DIRECT COMPARE"*, **greatest(nvl("COL A", "COL B"), nvl("COL B", "COL A")) "NVL COMPARE"**
from (
SELECT NULL "COL A", SYSDATE "COL B", SYSDATE "NEEDED RESULT" FROM DUAL UNION
SELECT SYSDATE - 180 , NULL  , SYSDATE - 180 FROM DUAL UNION
SELECT SYSDATE - 180 , SYSDATE , SYSDATE FROM DUAL ) A;
于 2019-11-12T12:00:19.937 回答