2011-05-13 4 views
0

J'ai un tableau qui suit les vues des produits.Groupe SQL par question

TrackId ProductId CreatedOn 
1  1   01/01/2011 
2  4   01/01/2011 
3  4   01/01/2011 
4  10  01/01/2011 

Ce que je veux faire est de retourner un ensemble de données qui n'a pas deux ProductIds l'un à côté de l'autre. I.e. à partir des données ci-dessus set je veux revenir:

TrackId ProductId CreatedOn 
1  1   01/01/2011 
2  4   01/01/2011 
4  10  01/01/2011 

Je ne peux pas utiliser distincte pour autant que je suis conscient que cela est basée sur les lignes?

Aide appréciée.

+1

Vous voulez dire "n'ayant pas de produit dans deux rangées adjacentes, adjacent est défini par suivant/précédent Trackid"? – gbn

Répondre

6

Générer une séquence row number par ProductID, prenez la première

;WITH cte AS 
(
    SELECT 
     *, 
     ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY TrackID) AS rn 
    FROM 
     MyProductTable 
) 
SELECT 
    TrackId ProductId CreatedOn 
FROM 
    cte 
WHERE 
    rn = 1 

Edit:

Si Si vous souhaitez utiliser un agrégat, vous devez d'abord avoir une sous-requête distincte pour garantir des résultats cohérents. Un MIN droit ne fonctionnera pas.

Ceci est basé sur mon commentaire à la question

"ne pas avoir ProductID en deux rangées adjacentes. A côté est défini par suivant/précédent TrackID"

SELECT 
    M.* 
FROM 
    myProductTable M 
    JOIN 
    (--gets the lowest TrackID for a ProductID 
    SELECT ProductID, MIN(TrackID) AS MinTrackID 
    FROM myProductTable 
    GROUP BY ProductID 
    ) M2 ON M.ProductID= M2.ProductID AND M.TrackID= M2.MinTrackID 
+0

+1 @izip, si vous n'avez pas utilisé les fonctions CTE et les fonctions de classement de SQL 2005+, alors apprenez-les. Ils vous serviront bien. –

+0

Merci, fera l'affaire. – izip

0

Vous pouvez GroupBy sur le TrackID et ProductID et faire un Min du CreatedOn si la date n'est pas importante.

SELECT TrackID ,ProductID ,MIN(CreatedOn) 
FROM [table] 
GROUP BY TrackID ,ProductID 

Si la date est le même que vous pouvez regrouper par tous les trois

SELECT TrackID ,ProductID ,CreatedOn 
FROM [table] 
GROUP BY TrackID ,ProductID ,CreatedOn 
+0

Je dois retourner l'ensemble de données complet. – izip

+0

Les deux donneront * toutes les lignes * dans la table parce que TrackID diffère ... – gbn

+0

@izip: vous ne pouvez pas avoir le "dataset complet" retourné si vous voulez supprimer quelques lignes – gbn

0
select min(TrackId), ProductId, CreatedOn 
from YourTable 
group by ProductId, CreatedOn; 
+1

Que faire si CreatedOn diffère pour un ProductId donné? Ensuite, vous avez la mauvaise sortie ... – gbn