在Teradata中获得EXPAND ON的所有月份

时间:2018-11-12 21:08:22

标签: sql datetime syntax teradata

我正在尝试使用EXPAND ON函数重写具有产品联接的查询,以扩展整个日期范围内的记录。这是目前的工作方式。

SELECT 
     t1.key
    ,MIN(t1.beg_dt)
    ,MAX(t1.end_dt)
    ,dates.end_month_dt
FROM t1
INNER JOIN dates
    ON t1.beg_dt < dates.end_month_dt
    AND t1.end_dt >= dates.end_month_dt
GROUP BY 1,4;

日期表只是一堆日期信息的列表。 end_month_dt是一列,每个月末的日期都可以追溯到几年前。 (例如1/31 / 13、2 / 28 / 31、3 / 31/13等)

如果t1中的记录的beg_dt = 1/1/13和end_dt = 8/31/13,则此联接将为此间隔中的每个月创建一条记录。像这样:

key    beg_dt    end_dt    end_month_dt
1      1/1/13    8/31/13   1/31/13
1      1/1/13    8/31/13   2/28/13
...
1      1/1/13    8/31/13   8/31/13

此查询运行不佳,必须分成几部分,因为它包含来自t1的更多信息,并且跨越了数年。我发现EXPAND ON可以产生非常相似的结果,但是在将最后一个月(或第一个月)包括在内时,我遇到了一个小问题。这是我所拥有的:

SELECT
     t1.key
    ,t1.beg_dt
    ,t1.end_dt
    ,BEGIN(prd) as end_month_dt
FROM t1
EXPAND ON PERIOD(t1.beg_dt, t1.end_dt) AS prd BY ANCHOR MONTH_END;

这将产生相同的结果,但不包括最后一行。如果我要使用END(prd),它将排除第一行。问题似乎是prd =(1/1/13,8/31/13)以及展开后返回的结果

prd
(1/31/13, 2/28/13)
(2/28/13, 3/31/13)
...
(7/31/13, 8/31/13)

我真正需要的是每个期间左侧的所有日期(1/31-7/31)的t1信息,然后是右侧的最后一个日期(8/31)的t1信息。还有另一种方式可以编写EXPAND ON以便得到结果吗?

编辑: 我发现,调整beg_dt和end_dt可以使我获得相同的结果,尽管它具有比通常包含的功能更多的功能。它似乎仍在运行,并且仍比原始版本快得多。

SELECT
     t1.key
    ,t1.beg_dt
    ,t1.end_dt
    ,BEGIN(prd) as end_month_dt
FROM t1
EXPAND ON PERIOD(
    CASE 
        WHEN beg_dt = Last_Day(beg_dt) THEN beg_dt + 1 
        ELSE beg_dt 
    END
   ,CASE 
        WHEN end_dt = '9999-12-31' THEN end_dt 
        ELSE end_dt + 1 
    END) AS prd BY ANCHOR Month_End

1 个答案:

答案 0 :(得分:0)

使用月初而不是月末作为锚点,然后提取最后包含的日期:

SELECT
     t1.key
    ,t1.beg_dt
    ,t1.end_dt
    ,Last(prd) as end_month_dt -- last included day = last day of the month
FROM t1
EXPAND ON PERIOD(t1.beg_dt, t1.end_dt) AS prd BY ANCHOR PERIOD MONTH_BEGIN;

ANCHOR PERIOD用于包含第一个月,如果beg_dt不是第一个月。

key      beg_dt        end_dt  end_month_dt  --  returned period 
1    2013-01-31    2013-08-31    2013-01-31  --  (2013-01-01, 2013-02-01)
1    2013-01-31    2013-08-31    2013-02-28  --  (2013-02-01, 2013-03-01)
1    2013-01-31    2013-08-31    2013-03-31  --  (2013-03-01, 2013-04-01)
1    2013-01-31    2013-08-31    2013-04-30  --  (2013-04-01, 2013-05-01)
1    2013-01-31    2013-08-31    2013-05-31  --  (2013-05-01, 2013-06-01)
1    2013-01-31    2013-08-31    2013-06-30  --  (2013-06-01, 2013-07-01)
1    2013-01-31    2013-08-31    2013-07-31  --  (2013-07-01, 2013-08-01)
1    2013-01-31    2013-08-31    2013-08-31  --  (2013-08-01, 2013-09-01)

编辑:

这应该返回与您编辑的查询相同的结果(排除beg_date,但包括end_dt,而句点包括开始并排除结束):

SELECT
     t1.KY
    ,t1.beg_dt
    ,t1.end_dt
    ,Begin(prd) AS end_month_dt
FROM t1
EXPAND ON PERIOD(beg_dt, end_dt) + INTERVAL '1' DAY AS prd BY ANCHOR Month_End