【问题标题】:How to show the last record of each customer for each month?如何显示每个客户每个月的最后一条记录?
【发布时间】:2021-11-04 10:42:21
【问题描述】:

请帮忙,我有一张表,其中包含过去 3 年客户记录的更改历史记录。 我需要输出每个客户在“每个”月的“最后一天”的状态或记录。

表格如下所示:

表 A:

| ID  | Name | Number|from_date(in Timestamp)|to_date(in Timestamp)|
|:--- |:----:|:-----:|----------------------:|--------------------:|
|123  | John | 101   |20210101 01:11:15      |20210103 01:11:15    | 
|123  | John | 102   |20210103 01:11:15      |20210301 01:11:15    | 
|123  | John | 103   |20210301 01:11:15      |20210325 01:11:15    | 
|123  | John | 104   |20210325 01:11:15      |20210415 01:11:15    | 
|123  | John | 105   |20210415 01:11:15      |20210416 01:11:15    | 
|123  | John | 106   |20210416 01:11:15      |20210525 01:11:15    |
|123  | John | 104   |20210525 01:11:15      |20210915 01:11:15    | 
|123  | John | 105   |20210915 01:11:15      |null                 |

鉴于以上数据,遗憾的是没有记录 2 月、6 月、7 月、8 月和 9 月的月份 但我需要显示“每个”月(1 月到 12 月)的客户数据。

预期的输出应如下所示:

| ID  | Name | Number|Date    |
|123  | John | 102   |20210131|
|123  | John | 102   |20210228|
|123  | John | 104   |20210331|
|123  | John | 106   |20210430|
|123  | John | 104   |20210531|
|123  | John | 104   |20210630|
|123  | John | 104   |20210731|
|123  | John | 104   |20210831|
|123  | John | 104   |20210931|

我可以通过下面的sql获取from_date列中可见的所有月份的最后一天记录。 但是对于未列出的月份或在from_dateto_date 列之间的月份,我正在努力展示它。

select a.id, a.name, a.number, last_day(a.from_date) Date
from (select a.*, row_number() over (partition by a.id, trunc(from_date, 'MON') 
order by from_date desc) as seqnum from tableA a
 ) a where seqnum = 1;

供大家参考,上面的sql输出如下:

| ID  | Name | Number|Date    |
|123  | John | 102   |20210131|
|123  | John | 104   |20210331|
|123  | John | 106   |20210430|
|123  | John | 106   |20210531|
|123  | John | 106   |20210931|

【问题讨论】:

  • 您的 Teradata 版本是什么?

标签: sql teradata teradatasql history-tables


【解决方案1】:

您可以使用 Teradata 的 EXPAND ON 子句。为此,我们从您的from_dateto_date 创建一个PERIOD 数据类型,然后使用EXPAND ON 将该时间段分成MONTH_END 块。

这看起来像:

 SELECT yourtable.*, BEGIN(bg) 
 FROM yourtable
 EXPAND ON PERIOD(from_date, NEXT(to_date)) AS by BY ANCHOR MONTH_END;

可能需要稍微调整一下语法,但它应该能让你进入球场。

【讨论】:

  • EXPAND ON 为我工作!非常感谢!
【解决方案2】:

TD 16.20+ 支持所谓的时间序列聚合。这应该会返回您的预期结果:

select id, name
  ,last(number)
  ,cast(end($TD_TIMECODE_RANGE) as date)
from table1
group by time(CAL_MONTHS(1) and id, name)
         using timecode (from_date) fill (previous)

【讨论】:

  • 嗨,这看起来很有趣!但我收到一个错误:No supported Time Series Aggregate function specified with the GROUP BY TIME clause. 你知道可能是什么原因造成的吗?
  • 在不知道实际 SQL 的情况下很难判断。时间序列不支持所有标准聚合函数:docs.teradata.com/r/mZqhP1sCTB4T74FbSzm7vA/…
  • 如果我可以在我的案例中使用时间序列聚合,我会尝试做更多的测试。谢谢你的想法!
  • 你好,我搜索了时间序列聚合函数,看起来我必须将我的表转换为临时表,但我可能错了。你有我可以使用上面的sql代码的示例表(表定义)吗?
  • 您不需要时序表,using timecode (from_date) 启用时序函数的使用。
猜你喜欢
  • 2021-01-23
  • 2014-07-31
  • 2011-12-17
  • 2017-02-19
  • 2018-06-28
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多