首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Teradata/SQL :如何使用teradata SQL比较连续行中的日期,并在结果上写case语句

Teradata/SQL :如何使用teradata SQL比较连续行中的日期,并在结果上写case语句
EN

Stack Overflow用户
提问于 2018-06-06 19:44:01
回答 1查看 464关注 0票数 0

我需要比较第一行的日期(end dt)和第二行的日期(strt dt),如果匹配,我需要提取第二行的strt dt。如果不匹配,我需要提取第一行的strt dt。一个订阅和通道包可以有多行。我发现在teradata中编写查询以获得所需的输出很困难。

下面是案例和预期结果。

案例1

代码语言:javascript
复制
Subscription    Channel package Start dt    End dt
11111112    Sports  7/3/2015    11/28/2015
11111112    Sports  4/1/2016    11/23/2016
11111112    Sports  11/23/2016  12/17/2017

需要输出

代码语言:javascript
复制
Subscription    Channel package Start dt    End dt
11111112    Sports  4/1/2016    12/17/2017

案例2

代码语言:javascript
复制
Subscription    Channel package Start dt    End dt
11111112    Sports  7/3/2015    11/28/2015
11111112    Sports  11/28/2015  4/1/2016
11111112    Sports  4/1/2016    11/23/2016
11111112    Sports  11/23/2016  12/17/2017

需要输出

代码语言:javascript
复制
Subscription    Channel package Start dt    End dt
11111112    Sports  7/3/2015    12/17/2017

我试过了,用

代码语言:javascript
复制
MIN(Start dt) OVER (PARTITION BY Subscription   , Channel package   
                    ORDER BY Start dt ROWS BETWEEN 1 FOLLOWING  AND 1 FOLLOWING
                   ) AS NXT Start dt

但不能更进一步,因为我在使用qualify时遇到了一些问题。

EN

回答 1

Stack Overflow用户

发布于 2021-05-12 03:33:10

我知道这可能是一个迟来的解决方案,也可能不是最快的解决方案。我会这样开始:

代码语言:javascript
复制
(
     SELECT
             TBL.SUBSCRIPTION
         ,   TBL.CHANNEL
         ,   TBL.SUBSCRIPTION || TBL.CHANNEL AS SUB_CHANNEL
         ,   CASE WHEN TBL.END_DT = TBL.START_DT THEN 1 ELSE 0 END AS SAME_DAY_FLAG
         ,   Dense_Rank() Over (ORDER BY SUB_CHANNEL ) AS GRP_RANK
         ,   TBL.START_DT
         ,   TBL.END_DT
         ,   PERIOD(TBL.START_DT, CASE WHEN TBL.END_DT > DATE THEN DATE ELSE TBL.END_DT + 1 END) AS COVERD_DTES
         
     FROM    <YOUR_TABLE> AS TBL
) WITH DATA
ON COMMIT PRESERVE ROWS;

根据需要创建索引。创建SUB_CHANNEL的原因是由于一些愚蠢的原因,我不能把手指放在上面,我无法为下面的一些函数拉出多个列。

代码语言:javascript
复制
/* Create a table that will contain the Merged rows with proper start and end dates combining adjacent periods*/

CREATE VOLATILE TABLE VT_TBL_MERGED_ROWS AS
(
    WITH  CTE (GRP_RANK, COVERD_DTES) AS
    (
        SELECT 
                GRP_RANK, COVERD_DTES
        FROM VT_PRE_CTE 
        
    )
    SELECT * FROM TABLE
    (    
        TD_SYSFNLIB.Td_Normalize_Overlap_Meet(NEW VARIANT_TYPE( CTE.GRP_RANK),  CTE.COVERD_DTES)
        RETURNS (GRP_RANK INT, COVERD_DTES PERIOD(DATE))
        HASH BY  GRP_RANK
        LOCAL ORDER BY GRP_RANK, COVERD_DTES
     )  AS TBL_ROWS
    
)   WITH DATA
PRIMARY INDEX (GRP_RANK);

函数TD_SYSFNLIB.Td_Normalize_Overlap_Meet标准化重叠的结束日期和开始日期,并分别为您提供最低和最后开始日期和结束日期的单行。因为我不能理解传递多个列的方法,所以我创建了GRP_RANK,然后我可以绑定它。

代码语言:javascript
复制
CREATE VOLATILE TABLE VT_PRE_OUTPUT AS 
(SELECT 
                A.SUBSCRIPTION
            ,   A.CHANNEL
            ,   A.GRP_RANK
            ,   B.COVERD_DTES
            ,   Min(A.EFF_DT) AS EFF_DT
            ,   Max(A.EXP_DT) AS EXP_DT
            ,   End(B.COVERD_DTES)- Begin(B.COVERD_DTES) AS TOTAL_DAYS
        FROM    VT_PRE_CTE AS A
        JOIN    VT_TBL_MERGED_ROWS AS B
        ON      A.GRP_RANK = B.GRP_RANK 
        AND     A.COVERD_DTES OVERLAPS B.COVERD_DTES
        GROUP BY 1,2,3) 
        WITH DATA 
        PRIMARY INDEX(MTN,  EXP_DT)
        ON COMMIT PRESERVE ROWS;

如果SUBSCRIPTION/CHANNEL组合之间有中断,则此A.COVERD_DTES OVERLAPS B.COVERD_DTES实际上会给您提供多行。您可以决定如何处理多个片段,既可以使用QUALIFY Row_Number() OVER(PARTITION BY SUBSCRIPTION, CHANNEL ORDER BY MIN_DT ASC) = 1获取第一个匹配项,也可以使用ORDER BY MIN_DT DESC)获取最新匹配项。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50719596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档