2010-05-12 5 views
2

J'ai SQLSQL question sous-requête

SELECT 
    Seq.UserSessionSequenceID, 
    Usr.SessionGuid, 
    Usr.UserSessionID, 
    Usr.SiteID, 
    Seq.Timestamp, 
    Seq.UrlTitle, 
    Seq.Url 
FROM 
    tblUserSession Usr 
INNER JOIN 
    tblUserSessionSequence Seq ON Usr.UserSessionID = Seq.UserSessionID 
WHERE  
    (Usr.Timestamp > DATEADD(mi, -45, GETDATE())) AND (Usr.SiteID = 15) 
ORDER BY Usr.Timestamp DESC 

suivant des choses assez simple. Il existe par nature plusieurs lignes UserSessionIDs dans tblUserSessionSequence. Je ne veux que retourner la dernière ligne (top 1) avec un seul UserSessionID. Comment je fais ça?

+0

double possible de [ "Simple" SQL Query] (http://stackoverflow.com/questions/246870/simple-sql-query) –

+0

Dernières usersessionid avec le plus gros UserSessionSequenceID –

Répondre

4

Vous pouvez utiliser la fonction de fenêtrage ROW_NUMBER numéroter les lignes pour chaque utilisateur et sélectionner uniquement les lignes qui ont le numéro de ligne 1.

SELECT 
    UserSessionSequenceID, 
    SessionGuid, 
    UserSessionID, 
    SiteID, 
    Timestamp, 
    UrlTitle, 
    Url 
FROM (
    SELECT 
     Seq.UserSessionSequenceID, 
     Usr.SessionGuid, 
     Usr.UserSessionID, 
     Usr.SiteID, 
     Usr.Timestamp AS UsrTimestamp, 
     Seq.Timestamp, 
     Seq.UrlTitle, 
     Seq.Url, 
     ROW_NUMBER() OVER (PARTITION BY Usr.UserSessionID 
          ORDER BY Seq.UserSessionSequenceID DESC) AS rn 
    FROM 
     tblUserSession Usr 
    INNER JOIN 
     tblUserSessionSequence Seq ON Usr.UserSessionID = Seq.UserSessionID 
    WHERE  
     (Usr.Timestamp > DATEADD(mi, -45, GETDATE())) AND (Usr.SiteID = 15) 
) T1 
WHERE rn = 1 
ORDER BY UsrTimestamp DESC 
+0

Laissez-moi en préciser un peu plus. Je veux toujours plusieurs lignes dans mon résultat global. Juste que veulent les premières années usersessionid uniques de tblUserSessionSequence –

+0

Obtenez cette erreur lorsque je tente de l'exécuter avec le code ci-dessus de vous: Msg 1033, niveau 15, état 1, ligne 21 La clause ORDER BY est invalide dans les vues, fonctions inline, tables dérivées, sous-requêtes et expressions de table communes, sauf si TOP ou FOR XML est également spécifié. –

+0

@ seo20: Essayez de supprimer l'ordre dans la sous-sélection et voyez si cela aide. J'ai mis à jour ma réponse. –

0

Si vous cherchez à retourner seulement une seule ligne dans votre requête (c.-à-ID avec le dernier horodatage), il suffit de changer

SELECT 

à

SELECT TOP 1 

Si vous cherchez à obtenir une seule ligne pour chaque UserSessionID, mais vous voulez vous assurer que vous obtenez celui avec la dernière TimeStamp, c'est un peu plus complexe.

Vous pouvez faire quelque chose comme ceci:

SELECT 
    Seq.UserSessionSequenceID, 
    Usr.SessionGuid, 
    Usr.UserSessionID, 
    Usr.SiteID, 
    Seq.Timestamp, 
    Seq.UrlTitle, 
    Seq.Url 
FROM 
    tblUserSession Usr 
INNER JOIN  
    (SELECT 
     UserSessionSequenceID, 
     UserSessionID, 
     Timestamp, 
     UrlTitle, 
     Url, 
     ROW_NUMBER() over (PARTITION BY UserSessionID ORDER BY UserSessionSequenceID) AS nbr 

    FROM tblUserSessionSequence) Seq ON Usr.UserSessionID = Seq.UserSessionID AND Seq.nbr = 0 
WHERE  
    (Usr.Timestamp > DATEADD(mi, -45, GETDATE())) AND (Usr.SiteID = 15) 
ORDER BY Usr.Timestamp DESC 
+0

Presque les travaux veulent UserSessionID avec le plus grand UserSessionSequenceID de tblUserSessionSequence. –

+0

@ seo20: Vous pouvez obtenir n'importe quel ordre en modifiant la clause 'ORDER BY' dans la sous-sélection. J'ai mis à jour la réponse pour donner ce que vous cherchez. –