【发布时间】:2014-09-17 01:37:18
【问题描述】:
我在一个表中有三列(日期类型),我想创建第四列,它需要包含前三列的最新日期。此外,前三列可以有 NULL 值。 除了使用 CASE 语句之外,Teradata 中是否有任何特殊功能或如何解决此问题的优雅方法?
【问题讨论】:
我在一个表中有三列(日期类型),我想创建第四列,它需要包含前三列的最新日期。此外,前三列可以有 NULL 值。 除了使用 CASE 语句之外,Teradata 中是否有任何特殊功能或如何解决此问题的优雅方法?
【问题讨论】:
有一个 GREATEST 函数,但如果任何日期为 NULL,它将返回 NULL。
作为一种解决方法,您可以将 NULL 与未使用的日期合并。如果所有三列都是 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 方法还不错,每个 WHEN 需要少一列:
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
【讨论】:
如果您使用的是 11g,则可以使用 unpivot 将列转换为单独的行,然后对这些行进行聚合。不确定这是否算“优雅”,但它不使用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 带有中间步骤。
内部查询会创建用于反透视的额外列,因为我认为您还想显示原始的三个值。如果您不这样做,那么您可以直接从您的表格中选择并取消旋转 col 等。
include nulls 子句意味着即使所有三个原始列都为空,它也会显示一行。如果这永远不会发生,或者您不想展示它,那么您可以忽略它。
【讨论】: