选择最近的日期

时间:2014-07-25 08:47:09

标签: sql oracle teradata

我在表中有三列(日期类型),我想制作第四列,需要包含前三列的最新日期。此外,前三列可以具有NULL值。 除了使用CASE语句之外,Teradata中是否有任何特殊功能或者如何解决这个问题的优雅方法?

2 个答案:

答案 0 :(得分:3)

有一个GREATEST函数,但如果任何日期为NULL,它将返回NULL。

作为一种解决方法,您可以使用未使用的日期对空值进行COALESCE。如果所有三列都为NULL,则最后可以应用NULLIF:

NULLIF(GREATEST(COALESCE(col1,DATE '0001-01-01')
               ,COALESCE(col2,DATE '0001-01-01')
               ,COALESCE(col3,DATE '0001-01-01')
               )
      , DATE '0001-01-01'
      )

Teradata支持TD14中的GREATEST功能,但由于奇怪的原因,它没有为DATE定义: - (

但是有一个解决方法:

CAST(NULLIF(GREATEST(COALESCE(CAST(col1 AS INT),-1)
           ,COALESCE(CAST(col2 AS INT),-1)                          
           ,COALESCE(CAST(col3 AS INT),-1)                          
           )
    ,-1) AS DATE)

顺便说一句,CASE方法并不是那么糟糕,每个W​​HEN需要少一列:

CASE
   WHEN COALESCE(col1, DATE '0001-01-01') >= COALESCE(col2, DATE '0001-01-01')
    AND COALESCE(col1, DATE '0001-01-01') >= COALESCE(col3, DATE '0001-01-01')
   THEN col1
   WHEN COALESCE(col2, DATE '0001-01-01') >= COALESCE(col3, DATE '0001-01-01')
   THEN col2
   ELSE col3
END

答案 1 :(得分:0)

如果您使用的是11g,则可以使用unpivot将cols转换为单独的行,然后聚合这些行。不确定这会被视为“优雅”,但它不会使用case ...

select id, col1, col2, col3, max(unpivot_col) as col4
from (
  select *
  from (
    select id, col1, col2, col3,
      col1 as x_col1, col2 as x_col2, col3 as x_col3
    from t42
  )
  unpivot include nulls (unpivot_col for col in (x_col1, x_col2, x_col3))
)
group by id, col1, col2, col3
order by id;

SQL Fiddle中间步骤。

内部查询创建了用于unpivot的额外列,因为我认为您还想显示原始的三个值。如果不这样做,那么您可以直接从表中选择并在col

上取消

include nulls子句意味着即使所有三个原始列都为空,它也会显示一行。如果这种情况永远不会发生,或者你不想表明它是否会发生,那么你就可以把它留下来。