2010-10-28 9 views
0

Je tableau un peu commeObtenir des données sur la même table

Name  |DateOfEvent|EventType 
---------------------------------- 
Smith  |10/1/2005 |New 
Thomas |1/1/2002 |Updated 
Johnson |6/1/2002 |New 
Smith  |7/1/2008 |Updated 
Smith  |7/1/2000 |New 

Je veux retourner les lignes où l'événement est dit nouveau et la date est avant une ligne avec le même nom mais le EventType est mis à jour une date ultérieure.

Ma pensée est d'itérer sur la table avec chaque ligne avec le nom, mais cela semble vraiment inefficace. Y a-t-il une meilleure manière de faire cela?

+0

pas sûr que je vous ai compris. Compte tenu de l'exemple ci-dessus, quels sont les résultats attendus? –

Répondre

3
CREATE TABLE #TEST 
(
    Name varchar(10), 
    DateOfEvent date, 
    EventType varchar(10) 
) 

INSERT INTO #TEST (Name, DateOfEvent, EventType) 
SELECT 'Smith',  '10/1/2005', 'New' UNION ALL 
SELECT 'Thomas', '1/1/2002', 'Updated' UNION ALL 
SELECT 'Johnson', '6/1/2002', 'New' UNION ALL 
SELECT 'Smith',  '7/1/2008', 'Updated' UNION ALL 
SELECT 'Smith',  '7/1/2000', 'New' 

SELECT NEW.* FROM 
    (SELECT Name, MAX(DateOfEvent) AS DateOfEvent 
     FROM #TEST 
     WHERE EventType = 'Updated' 
     GROUP BY Name 
    ) UPDATED 
    JOIN 
    (SELECT Name, MIN(DateOfEvent) AS DateOfEvent 
     FROM #TEST 
     WHERE EventType = 'New' 
     GROUP BY Name 
    )New ON New.DateOfEvent < UPDATED.DateOfEvent AND New.Name = UPDATED.Name 
+0

Excellent exemple de travail complet. – Maestro1024

3
SELECT 
    e1.* 
FROM 
    Events e1, 
    Events e2 
WHERE 
    e1.EventType = 'New' and 
    e1.Name = e2.Name and 
    e2.EventType = 'Updated' and 
    e2.DateOfEvent > e1.DateOfEvent; 

Ou la même chose avec rejoindre:

SELECT 
    e1.* 
FROM 
    Events e1 
INNER JOIN 
    Events e2 
ON 
    e1.Name = e2.Name 
WHERE 
    e1.EventType = 'New' and 
    e2.EventType = 'Updated' and 
    e2.DateOfEvent > e1.DateOfEvent; 
+0

Je pense que vous avez inversé la comparaison de vos dates. La date mise à jour doit être * postérieure à * la nouvelle date. –

+0

Ce que Joe a dit - Actuellement ça ne marche pas. –

+0

Bien sûr. Fixé en réponse. – Kel

1

Peut-être que quelque chose le long des lignes de:

SELECT 
    t1.Name, 
    t1.DateOfEvent, 
    t1.EventType 
FROM table t1 
LEFT JOIN table t2 
    t1.Name = t2.Name 
WHERE 
t1.EventType = 'New' AND t1.DateOfEvent < t2.DateOfEvent AND t2.EventType = 'Updated' 

Cette requête utilise Name pour faire le JOIN, mais les noms pourraient ne pas rester unique en tant que la table grandit. L'introduction d'une clé primaire et d'identifiants parents pour suivre l'historique fonctionnera probablement mieux.

+0

Est-ce supposer 2 tables? t1 et t2? – Maestro1024

+1

@ Maestro1024: n ° t1 et t2 sont des alias de la même table. C'est ce qu'on appelle une auto-jointure. Si vous regardez la requête, vous voyez que le tablenime est le même, c'est-à-dire "table". – Saul

+0

Je vois. Merci pour l'aide. – Maestro1024

1

Utilisation:

SELECT x.name, 
     x.dateofevent, 
     x.eventtype 
    FROM YOUR_TABLE x 
WHERE x.eventtype = 'New' 
    AND EXISTS(SELECT NULL 
       FROM YOUR_TABLE y 
       WHERE y.name = x.name 
       AND y.eventtype = 'Updated' 
       AND y.dateofevent > x.dateofevent) 

Le problème avec l'utilisation de JOIN (intérieur ou extérieur) est que s'il y a plus d'un enregistrements qui sont marqués « mis à jour » avec une date antérieure à la « nouvelle » un - il y aura des doublons des références x.

Questions connexes