0

我认为使用 CTE 和 TD_NORMALIZE_MEET 会帮助我。我有多行,说

**FIELD1    |   FIELD2  |    FIELD3 |    FIELD4 |    START_DT   |    END_DT**
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2019/09/23 |    2019/09/30
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2019/10/01 |    2019/10/25
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2019/11/01 |    2019/11/30
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2019/12/01 |    2019/12/25
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2019/12/26 |    2020/01/10
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2020/01/15 |    2020/01/30
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2020/01/31 |    2020/03/20
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2020/03/28 |    2020/05/25
abcd1   |    efgh1  |    hijk1  |     lmno1 |    2020/06/01 |    2020/09/01

这些应该作为

**FIELD1    |   FIELD2  |   FIELD3  |   FIELD4  |   START_DT    |   END_DT**
abcd1   |   efgh1   |   hijk1   |   lmno1   |   2019/09/23  |   2019/10/25
abcd1   |   efgh1   |   hijk1   |   lmno1   |   2019/11/01  |   2020/01/10
abcd1   |   efgh1   |   hijk1   |   lmno1   |   2020/01/15  |   2020/03/20
abcd1   |   efgh1   |   hijk1   |   lmno1   |   2020/03/28  |   2020/05/25
abcd1   |   efgh1   |   hijk1   |   lmno1   |   2020/06/01  |   2020/09/01

但是,TD_NORMALIZE_MEET 并没有帮助。尝试了 TD_NORMALIZE_OVERLAP_MEET 和所有其他技巧。任何帮助是极大的赞赏。我什至尝试通过在结束日期添加一天来使用 TD_NORMALIZE_OVERLAP_MEET,但这会以不同的方式混淆数据。因此,我必须遵守日期,但以将它们组合在一起的方式合并日期,以获得最低连续期间的最小开始日期和最高连续期间的最大结束日期。

4

2 回答 2

0

因此,为了继续解决我的问题,并且感谢同样在这里的人们提供的一些精彩提示,我必须要有创意。一个是使用 CTE(公用表表达式),另一个是为我拥有的 4 个字段组创建一个不同的 ID 字段,因为我以某种方式传递了任何非整数并且多个字段不适用于我使用的 TD_NORMALIZE_OVERLAP_MEET。

我仍在寻找一种解决方案来使用多个组列,非 INT 类型与 TD_NORMALIZE... 函数。请协助。

正如 Fred 上面建议的那样,如果下一个开始日期相邻,我确实必须延长结束日期以与下一个开始日期重叠。我使用 DENSE_RANK 以便数字从一组到另一组是连续的。

所以

CREATE VOLATILE TABLE TBL1 AS
(
    SELECT 
        FIELD1, 
        FIELD2, 
        FIELD3, 
        FIELD4, 
        DENSE_RANK() OVER(PARTITION BY FIELD1, FIELD2, FIELD3, FIELD4 
                            ORDER BY START_DT ASC) AS GRP_RANK, 
        START_DT, 
        END_DT, 
        PERIOD(START_DT, END_DT + 1) AS COVERED_PERIOD
    FROM MYTABLE
) WITH DATA
PRIMARY INDEX (FIELD1, FIELD2, FIELD3, FIELD4, SAME_DAY_FLAG)
INDEX (GRP_RANK) ON COMMIT PRESERVE ROWS;

用它来创建合并表。

CREATE VOLATILE TABLE TBL_MERGED AS
( 
    WITH CTE(GRP_RANK, COVERED_PERIOD) AS
    (
        SELECT 
            GRP_RANK, 
            COVERED_PERIOD 
        FROM TBL1 
    )
    SELECT * FROM TABLE
    (   TD_SYSFNLIB.TD_NORMALIZE_OVERLAP_MEET(NEW VARIANT_TYPE(CTE.GRP_RANK), CTE.COVERED_PERIOD)
        RETURNS(GRP_RANK INT, COVERED_PERIOD PERIOD(DATE))
        HASH BY GRP_RANK
        LOCAL ORDER BY GRP_RANK, COVERED_PERIOD
    ) AS TBL_ROWS
)WITH DATA ON COMMIT PRESERVE ROWS;

然后我用我的 tbl1 加入了它

SELECT 
        A.FIELD1, 
        A.FIELD2, 
        A.FIELD3, 
        A.FIELD4, 
        A.GRP_RANK, 
        A.COVERED_PERIOD, 
        MIN(A.START_DT) AS START_DT, 
        MAX(A.END_DT) AS END_DT
FROM    TBL1 AS A
JOIN    TBL_MERGED AS B
ON      A.GRP_RANK = B.GRP_RANK
AND     A.COVERED_PERIOD OVERLAPS B.COVERED_PERIOD
GROUP BY 1,2,3,4,5,6
ORDER BY 1,2,3,4,7 
于 2020-09-25T03:00:07.667 回答
0

正如您所提到的,您将不得不操作 END_DT 因为NORMALIZE选项需要 PERIOD 数据类型,并且 PERIOD 语义是“最多但不包括”结束日期时间值。

select field1, field2, field3, field4, begin(pd) as Start_DT, prior(end(pd)) as End_DT
from (
  select normalize field1, field2, field3, field4, period(Start_DT,next(End_DT)) as pd
  from My_Table) Norm_Tbl
于 2020-09-23T20:11:03.770 回答