2010-05-11 7 views
1

Ma table ressemble à ceci avec doublons dans col1choisir col1 distinct avec min (col2) et max (col3) de la table

col1,  col2,  col3,  col4 
1,   1,   0,   a 
1,   2,   1,   a 
1,   3,   1,   a 
2,   4,   1,   b 
3,   5,   0,   c 

Je veux choisir col1 distinct avec max (col3) et min (col2) ; si le jeu de résultats sera:

col1,  col2,  col3,  col4 
1,   2,   1,   a 
2,   4,   1,   b 
3,   5,   0,   c 

J'ai une solution, mais la recherche de meilleures idées?

Répondre

4
SELECT col1, MAX(col3) AS col3, MIN(col2) AS col2, MAX(col4) AS col4 
FROM MyTable 
GROUP BY col1; 

Vous avez montré dans votre exemple que vous vouliez un col4 inclus, mais vous ne dites pas quelle valeur que vous voulez. Vous devez placer cette colonne dans une fonction d'agrégat ou dans la clause GROUP BY. J'ai supposé que prendre le maximum pour le groupe serait acceptable.


mise à jour: Merci pour la clarification. Vous posez des questions sur une variante du problème le plus important par groupe qui survient fréquemment dans Stack Overflow. Voici ma solution habituelle:

SELECT t1.* 
FROM mytable t1 
LEFT OUTER JOIN mytable t3 
ON t1.col1 = t3.col1 AND t1.col3 < t3.col3 
WHERE t3.col1 IS NULL; 

En anglais: me montrer la ligne (t1) pour lesquels aucune ligne existe avec le même col1 et une plus grande valeur dans col3. Certaines personnes écrivent ceci en utilisant un prédicat sous-requête NOT EXISTS, mais je préfère la syntaxe JOIN.

est ici la sortie de mon test donné vos données d'exemple:

+------+------+------+------+ 
| col1 | col2 | col3 | col4 | 
+------+------+------+------+ 
| 1 | 2 | 1 | a | 
| 1 | 3 | 1 | a | 
| 2 | 4 | 1 | b | 
| 3 | 5 | 0 | c | 
+------+------+------+------+ 

Notez qu'il ya deux lignes pour col1 valeur 1, parce que les deux lignes satisfont à la condition de jointure; aucune autre ligne n'existe avec valeur supérieure dans col3. Nous avons donc besoin d'ajouter une autre condition pour résoudre l'égalité. Vous souhaitez comparer aux lignes avec moins la valeur dans col2 et si aucune ligne n'existe, nous avons trouvé la ligne avec la valeur la plus faible dans col2.

SELECT t1.* 
FROM MyTable t1 
LEFT OUTER JOIN MyTable t3 
ON t1.col1 = t3.col1 AND t1.col3 < t3.col3 
LEFT OUTER JOIN MyTable t2 
ON t1.col1 = t2.col1 AND t1.col3 = t2.col3 AND t1.col2 > t2.col2 
WHERE t2.col1 IS NULL AND t3.col1 IS NULL; 

est ici la sortie de mon test donné vos données d'exemple:

+------+------+------+------+ 
| col1 | col2 | col3 | col4 | 
+------+------+------+------+ 
| 1 | 2 | 1 | a | 
| 2 | 4 | 1 | b | 
| 3 | 5 | 0 | c | 
+------+------+------+------+ 

PS: Par ailleurs, il est d'usage sur Stack Overflow pour modifier votre question initiale et ajouter des détails, au lieu d'ajouter des réponses à votre propre question qui ne fait que clarifier la question. Mais je sais que certaines actions ne sont pas disponibles jusqu'à ce que vous ayez plus d'un point de réputation.

+0

Obtient mon vote pour ne pas avoir un alias de table inutile, mais vous manquez des points bonus en ne nommant pas vos sorties de colonne :) – sidereal

+0

@sidereal: Point pris. J'ai modifié pour ajouter des alias de colonne. –

+0

Merci Bill! Ça marche pour moi – user338804