简体   繁体   中英

Teradata Sql query

I have data as follows in a Table ( 3 columns ):

Name    StartDt         EndDt
 A     01/01/2009    12/31/2009
 A     01/01/2010    11/30/2010
 B     03/01/2011    10/31/2011
 A     04/01/2012    12/31/2012
 A     01/01/2013    08/01/2013

Now I want to create a Output using Terdata Sql query as follows:

Name    Min_Startdt    Max_Startdt
 A       01/01/2009    11/30/2010
 A       04/01/2012    08/01/2013
 B       03/01/2011    10/31/2011

Please let me how this can be achieved via a Teradata Query

Here is one approach:

SELECT name
     , grp
     , MIN(StartDt)
     , MAX(EndDt)
  FROM (
        SELECT t.*
             , SUM(keepwithnext) 
                   OVER (PARTITION BY  name 
                             ORDER BY startdt 
                         ROWS UNBOUNDED PRECEDING
                        ) AS grp
          FROM (
                 SELECT t.*
                      , CASE WHEN t2.name is null 
                              THEN 0 
                              ELSE 1 
                         END   AS keepwithnext
                   FROM t AS t
                   LEFT OUTER 
                   JOIN t AS t2
                     ON     t.name  = t2.name 
                        AND t.enddt = t2.StartDt - 1
                 ) AS t
        ) AS t
GROUP BY name, grp;

The idea is to determine when each sequence of dates ends. A sequence continues while the next start date is one day later than the given end date. This is what the innermost subquery does.

Then, for each name, calculate a cumulative sum of "ends". All the rows with the same "grp" value are in a sequence. The outside query then aggregates these together.

you can try doing a query that looks like this

select distinct * from (
    select name,
    min(startdt) over(partition by name) as startdt,
    max(enddt) over(partition by name) as enddt)
    a

this should work...

In TD13.10 you might use one of the new time series functions for periods, TD_NORMALIZE_OVERLAP_MEET or TD_NORMALIZE_MEET, which combine all rows which meet (end of one row = start of next row) and/or overlap (end of one row > start of next row).

As a the ending date of a PERIOD is exclusive by definition you have to adjust your EndDt by adding 1.

WITH cte(name, pd) AS
 (
   SELECT
      name
      ,PERIOD(StartDt, EndDt+1) AS pd
   FROM dropme
 )
SELECT
   name
   ,BEGIN(pd) AS StartDt
   ,LAST(pd) AS EndDt -- latest including date, same as END(pd)-1
   ,cnt
FROM TABLE (TD_NORMALIZE_OVERLAP_MEET
           (NEW VARIANT_TYPE(cte.name)
            ,cte.pd)
            RETURNS (name VARCHAR(...) 
                    ,pd PERIOD(DATE)
                    ,cnt INTEGER)-- optional, number of rows combined
            HASH BY name
            LOCAL ORDER BY name, pd
        ) AS dt
ORDER BY 1,2

Dieter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM