Teradata,交易数据,其中列具有单独的更新日期

时间:2018-05-20 05:44:21

标签: sql teradata

我正在研究Teradata查询,我想查找多列的最新值。每个数据列都与日期列(更新日期)相关。 我的表格标题应该有助于理解我的问题: ID Attr_1 Attr_1_Update_Dt Attr_2 Attr_2_Update_Dt Attr_3 Attr_3_Update_Dt

我需要选择Attr_1,Attr_2和Attr_3作为每个属性的最新更新日期(对于每个ID)。 我已经考虑过为每个属性运行各个等级(通过更新dt),然后将它们连接到一个表中。但我不认为这太复杂了(当我有8个属性列时更多)。

希望以上内容足以帮助我。期待收到你的回复。

谢谢!

2 个答案:

答案 0 :(得分:0)

有几种方法可以获得结果。

您可以为每个其他属性应用FIRST_VALUE:

select
   Attr_1, Attr_1_Update_Dt,
   first_value(Attr_2) over (order by Attr_2_Update_Dt DESC),
   max(Attr_2_Update_Dt ) over (),
   ...
   first_value(Attr_n) over (order by Attr_n_Update_Dt DESC),
   max(Attr_2_Update_Dt ) over ()
from myTable
qualify row_number() over (order by Attr_1_Update_Dt DESC) = 1 -- only 1 row

这需要在Explan中为每个属性添加额外的STATS步骤,当表很大时,资源使用率可能会很高。

在这种情况下,规范化表可能会提高性能:

select 1 as attr#, Attr_1, Attr_1_Update_Dt from myTable
union all 
select 2 as attr#, Attr_2, Attr_2_Update_Dt from myTable
...
union all
select n as attr#, Attr_n, Attr_n_Update_Dt from myTable

或CROSS JOIN到表中编号为1到n的表(可能效率更高):

select 
   num as attr#, 
   case when num = 1 then Attr_1 end,
   case when num = 1 then Attr_1_Update_Dt end,
   case when num = 2 then Attr_2 end,
   case when num = 2 then Attr_2_Update_Dt end,
   ...
   case when num = n then Attr_1 end,
   case when num = n then Attr_1_Update_Dt end
from myTable 
cross join
  (
    Select returning "num" from 1 to n
  ) dt

或者在较新版本中使用TD_UNPIVOT或UNPIVOT ......

然后它是一个简单的

select *
from 
 (
   normalizing Select
 ) as dt
qualify
   row_number()
   over (partition by num
         order by Attr_1_Update_Dt DESC) = 1

答案 1 :(得分:0)

我希望看到您以规范化的方式存储数据。在此之前,您将需要更复杂的查询才能执行此类任务。

处理数据的方法是使用GREATEST()函数但由于某些原因只有Teradata开发人员知道这个函数不接受日期,但它们可能被转换为它接受的整数。还有必要避免使用NULL。这可以为您提供每行的最新日期,然后您可以使用ROW_NUMBER()来获取每个ID最近日期的行。

.sample{style here...}

我对这种方法的性能无法准确,它可能最适合适度的表格大小。如果你的表非常大,那么我真的会探索规范化数据的选项。