2010-03-22 5 views
1

J'ai une table de données qui représente une série d'événements que les personnes font au fil du temps, parfois les gens font la même chose plusieurs fois de suite. Comment sélectionner un résultat à l'aide de MS SQL 2008 qui montre uniquement les séquences désambiguïsées de ces événements?Comment désambiguïser une séquence en SQL?

Source data: 
Person Event Time 
1  2  1 
1  2  20 
1  2  33 
2  1  34 
1  4  43 
1  2  44 
2  3  45 
1  2  46 
1  3  50 
1  3  55 

Result: 
Person Event 
1  2 
2  1 
1  4 
1  2 
2  3 
1  3 
+2

définir désambiguïsé? Premier? dernier? – TomTom

+0

J'ai regardé la séquence de résultats trois fois et je n'arrive toujours pas à comprendre les règles utilisées pour la construire. Pouvez-vous expliquer un * lot * de plus, s'il vous plaît? –

+0

J'ai besoin d'une liste où AUCUN deux événements Simlar de la même personne ne se suivent dans le temps. Si la séquence est 2 2 2 4 4 2 2 3 3 3 4 4, alors j'ai besoin de 2 4 2 3 4. – Martin

Répondre

2

essayez ceci:

DECLARE @YourTable table (Person int, Event int, Time int) 
SET NOCOUNT ON 
INSERT INTO @YourTable VALUES (1, 2 , 1) 
INSERT INTO @YourTable VALUES (1, 2 , 20) 
INSERT INTO @YourTable VALUES (1, 2 , 33) 
INSERT INTO @YourTable VALUES (2, 1 , 34) 
INSERT INTO @YourTable VALUES (1, 4 , 43) 
INSERT INTO @YourTable VALUES (1, 2 , 44) 
INSERT INTO @YourTable VALUES (2, 3 , 45) 
INSERT INTO @YourTable VALUES (1, 2 , 46) 
INSERT INTO @YourTable VALUES (1, 3 , 50) 
INSERT INTO @YourTable VALUES (1, 3 , 55) 
SET NOCOUNT OFF 

;WITH Ranked AS 
(SELECT 
    Person,Event,Time 
    ,ROW_NUMBER() OVER(PARTITION by Person order by time,Person, Event) AS RowNumber 
    FROM @YourTable 
) 
SELECT 
    r1.Person,r1.Event 
    FROM Ranked    r1 
     LEFT OUTER JOIN Ranked r2 ON r1.RowNumber=r2.RowNumber-1 AND r1.Person=r2.Person 
    WHERE r1.Event!=ISNULL(r2.Event,-999) 

SORTIE:

Person  Event 
----------- ----------- 
1   2 
1   4 
1   2 
1   3 
2   1 
2   3 

(6 row(s) affected) 

OP ne dit pas quelle version de SQL Server, alors voici la CTE version gratuite pour pré SQL Server 2005, même sortie que ci-dessus:

SELECT 
    r1.Person,r1.Event 
    FROM (SELECT 
       Person,Event,Time 
       ,ROW_NUMBER() OVER(PARTITION by Person order by time,Person, Event) AS RowNumber 
       FROM @YourTable 
     ) r1 
     LEFT OUTER JOIN (SELECT 
          Person,Event,Time 
          ,ROW_NUMBER() OVER(PARTITION by Person order by time,Person, Event) AS RowNumber 
          FROM @YourTable 
         ) r2 ON r1.RowNumber=r2.RowNumber-1 AND r1.Person=r2.Person 
    WHERE r1.Event!=ISNULL(r2.Event,-999) 
+0

pas jolie, mais efficace! est-ce que SQL Server 2008 a la fonction analytique lag()? (Je sais que 2005 ne l'est pas) Si c'était le cas, vous pourriez le faire sans avoir à utiliser un CTE/scanner la table deux fois. – araqnid

-1

Personne select, événement, dernière (temps) du groupe X par personne, événement

+2

LAST est MS Access seulement je pense. Aurait besoin d'utiliser une autre agrégation. –

0

Je ne sais pas si je vous ai droit. Peut-être que vous voulez

SELECT DISTINCT Person, Event FROM Table Where 1 ORDER BY Person; 

Ceci sélectionne toutes vos lignes, mais supprime les doublons. Donc, cela devrait donner:

Result: 
Person Event 
1  2 
1  4 
1  3 
2  1 
2  3 
+0

Cela ne fonctionne pas - Utiliser distinct dans cette forme perd l'unicité de la séquence, j'ai juste besoin de fusionner les événements similaires qui se succèdent dans le temps. Si la séquence est 2 2 2 4 4 2 2, alors j'ai besoin de 2 4 2. – Martin

0

Je préfère COUNT < -> GROUP BY sur DISTINCT

SELECT Person, Event, COUNT(Time) Amount FROM Table GROUP BY Person, Event ORDER BY COUNT(Time) DESC 
+0

renvoie de mauvais résultats. la sortie devrait être (1,2) (1,4) puis (1,2) cette méthode élimine tous les doublons –

Questions connexes