我正在尝试使用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
答案 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