1

我正在尝试重写具有产品连接的查询,以使用 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)。有没有另一种方法可以让我在 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
4

1 回答 1

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 PERIODbeg_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
于 2018-11-12T22:12:52.170 回答