【问题标题】:How to show the latest record for "each" month given only a date range of each records如何在仅给定每个记录的日期范围的情况下显示“每个”月的最新记录
【发布时间】:2021-11-19 18:15:10
【问题描述】:

我有一个历史表,其中包含每个客户的记录,其中 start_date 和 end_date 列指示每行的有效期。该表如下所示:

| ID  | Name | Code  |start_date (Timestamp) |end_date (Timestamp) |
|:--- |:----:|:-----:|----------------------:|--------------------:|
|123  | John | 100   |2021/1/6   8:00:00     |2021/1/31  8:00:00   | 
|123  | John | 101   |2021/1/31  8:00:00     |2021/2/15  8:00:00   | 
|123  | John | 102   |2021/2/15  8:00:00     |2021/3/15  8:00:00   | 
|123  | John | 103   |2021/3/15  8:00:00     |2021/6/15  9:00:00   | 
|123  | John | 105   |2021/6/15  9:00:00     |2021/6/15  9:15:00   | 
|123  | John | 106   |2021/6/15  9:15:00     |2021/6/15 10:00:00   |
|123  | John | 107   |2021/6/15 10:00:00     |2021/7/15 15:00:00   | 
|123  | John | 108   |2021/7/15 15:00:00     |null                 |

我决定使用“展开”功能来生成一个显示“每月”记录(每月结束记录)的列。所需的输出应该是这样的,如果 end_date 为空,它应该将记录展开到当前日期,但我的展开语法不能正常工作:

| ID  | Name | Code  |start_date (Timestamp) |end_date (Timestamp) |end_of_month
|---- |------|-------|-----------------------|---------------------|------------
|123  | John | 101   |2021/1/31  8:00        |2021/2/15  8:00:00   | 2021/1/31
|123  | John | 102   |2021/2/15  8:00        |2021/3/15  8:00:00   | 2021/2/28
|123  | John | 103   |2021/3/15  8:00        |2021/6/15  9:00:00   | 2021/3/31
|123  | John | 103   |2021/3/15  8:00        |2021/6/15  9:00:00   | 2021/4/30
|123  | John | 103   |2021/3/15  8:00        |2021/6/15  9:00:00   | 2021/5/31
|123  | John | 107   |2021/6/15 10:00        |2021/7/15 15:00:00   | 2021/6/30
|123  | John | 108   |2021/7/15 15:00        |?                    | 2021/7/30
|123  | John | 108   |2021/7/15 15:00        |?                    | 2021/8/31
|123  | John | 108   |2021/7/15 15:00        |?                    | 2021/9/30

我有以下 sql,但它不包括最后一条记录,即 end_of 月“2021/9/30”。 如果我将 ANCHOR 设置为“MONTH_BEGIN”,则会出现“2021/9/30”记录,但会排除 2021/7/30 记录。

select a.id, a.name, a.code, a.start_date, a.end_date, last_day(BEGIN(bg2)) 
as end_of_month from (select id, name, code, start_date, end_date, 
period(start_date,COALESCE(MIN(start_date) OVER (PARTITION BY name ORDER BY start_date 
ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING), CURRENT_TIMESTAMP)) as bg from CHESS.HST) as a
expand on bg as bg2 by ANCHOR MONTH_END

【问题讨论】:

  • 你可以直接add_months(CURRENT_TIMESTAMP, 1)
  • 您好,很抱歉,您能详细说明一下吗?我尝试在末尾部分使用 add_months,例如 where bg2 > add_months(current_timestamp,-1) 来获取上个月的记录,但出现错误。看起来 add_months 不能用于扩展列
  • 不,是在创建周期。顺便说一句,根据您的数据,您不需要 MIN/OVER,它已经包括开始和结束..
  • 对不起,我不明白,我真的是 sql 新手。如果您能帮助我理解如何编写它,我将不胜感激。
  • 这就是 dnoeth 的意思。您想在月经期间使用它:period(start_date,coalesce(end_date,add_months(current_timestamp,1))) as bg

标签: sql teradata expand teradatasql history-tables


【解决方案1】:

这似乎符合您要求的结果:

select a.id, a.name, a.code, a.start_date, a.end_date,
   last_day(begin(bg2)) as end_of_month
from
 (
   select id, name, code, start_date, end_date, 
      period(start_date,COALESCE(end_date
                                ,add_months(CURRENT_TIMESTAMP(0), 1)
                                )
            ) as bg
   from HST
 ) as a
expand on bg as bg2 
    by ANCHOR MONTH_END

【讨论】:

  • 我刚刚意识到扩展是如何工作的,现在我明白了为什么我需要在此期间增加 1 个月。非常感谢!但我不确定的一件事是,expand_on ANCHOR MONTH_END "always" 会在展开前选择一个月的最新记录吗?因为如果一天中有多条记录,其时间戳相差 1 分钟或几秒,我想知道 expand_on 是否总是会选择最新的。
  • 不,它不会选择 latest 行,EXPAND 是基于行的,因为每一行都被展开,您可能在同一月份有多个行。我对您上一个问题的回答显示了如何每月获得一行:stackoverflow.com/a/69094883/2527905
  • 我承认我对锚位感到困惑,但我认为使用 MONTH_END 会导致第一行 (2021-01-06) 脱落。如果您使用 DAY 之类的内容,您将看到该日期的行。
  • 我已经测试过很多次了。幸运的是,我的表在每个月底只包含 1 条记录,所以我接受这个作为答案。非常感谢@dnoeth!
  • 嗨@Andrew,你是对的! expand on month_end 有一点问题。由于时区差异,end_of_month 列中的日期和时间信息不正确。更改时区间隔设置将解决问题,但对于 Views 似乎不可能。
猜你喜欢
  • 1970-01-01
  • 2020-08-03
  • 2023-01-12
  • 1970-01-01
  • 2014-06-29
  • 2022-12-03
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
相关资源
最近更新 更多