2013-05-24 2 views
1

j'ai données comme suit dans un tableau (3 colonnes):Teradata Sql requête

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 

Maintenant, je veux créer une sortie en utilisant la requête Terdata Sql comme suit:

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 

S'il vous plaît laissez-moi comment cela peut être réalisé par une Teradata Query

+0

Qu'est-ce que vous essayez d'atteindre exactement? comment différencier les rangées où 'Name = 'A''? – ChrisCamp

+0

@ChrisCamp Fondamentalement, je veux regrouper autant que possible les lignes correspondant à la valeur particulière du nom de la colonne. Si vous voyez la sortie a deux lignes pour Name = A mais la première ligne est une combinaison des 2 premières lignes de la table d'entrée pour Name = A.Similarily la deuxième ligne d'Ouput pour Name = A est la combinaison des lignes 5 et 6 de Table d'entrée pour le nom = A. Est-ce utile? – user2417881

Répondre

2

Voici une approche:

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; 

L'idée est de déterminer quand chaque séquence de dates se termine. Une séquence continue alors que la date de début suivante est un jour plus tard que la date de fin donnée. C'est ce que fait la sous-requête la plus interne. Puis, pour chaque nom, calculez une somme cumulative de "fins". Toutes les lignes avec la même valeur "grp" sont dans une séquence. La requête externe les agrège ensuite ensemble.

0

vous pouvez essayer de faire une requête qui ressemble à ceci

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

cela devrait fonctionner ...

0

En TD13.10 vous pouvez utiliser l'une des nouvelles fonctions de séries temporelles pour les périodes, ou TD_NORMALIZE_OVERLAP_MEET TD_NORMALIZE_MEET, qui combine toutes les lignes qui se rencontrent (fin d'une ligne = début de la ligne suivante) et/ou chevauchement (fin d'une ligne> début de la ligne suivante).

En tant que la date de fin d'une période est exclusive par définition, vous devez ajuster votre EndDt en ajoutant 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

Questions connexes