2009-11-24 3 views
1

J'apprends le SQL pour un projet personnel et semble ne pas avoir la fonction COUNT.La fonction de compte SQL Oracle n'affiche qu'une seule valeur

J'ai une table "échantillon" avec ces données d'échantillon:

  • NOM DE LA COULEUR
  • Tom rouge
  • Tom bleu
  • Jerry jaune
  • Keri jaune
  • Paul rouge
  • Bob jaune
  • Bob rouge
  • Mary vert

Ce que je suis tenté de faire est d'imprimer sur uniquement les valeurs NOM qui ont seulement une valeur de couleur qui est jaune.

Voici la requête que j'ai écrite mais Bob sort, ce qui est une erreur.

SELECT COUNT(NAME),NAME 
FROM SAMPLE 
WHERE (COLOR = 'yellow') 
HAVING COUNT(*) = 1 
GROUP BY NAME; 

Quelqu'un peut-il me dire ce que je fais de façon incorrecte?

Merci.

Répondre

3

Il est parce que votre article where limite le jeu de résultats avant la clause having vérifie.

D'où vous supprimez bob red de sorte que le seul bob gauche est le yellow un. Et il aura un compte de 1.

Celui-ci travaille pour moi (bien que dans DB2, mais depuis que je tendance à préférer la norme SQL, il devrait fonctionner sur tout SGBD):

select count(a.name), a.name 
from sample a, 
    (select name from sample where color = 'yellow') b 
where a.name = b.name 
group by a.name 
having count(a.name) = 1; 

retours jaune (pas Bob):

-------- 
    NAME 
-------- 
1 Jerry 
1 Keri 

tandis que les rendements rouges (pas Tom ou Bob):

------- 
    NAME 
------- 
1 Paul 

La façon dont cela fonctionne est la suivante:

  • Une sous-requête est exécutée pour obtenir une liste de tous les noms qui ont la couleur jaune. Ils peuvent également avoir d'autres couleurs à ce stade. Cela limite les noms à Jerry, Keri et Bob.
  • Ensuite, la requête "réelle" est exécutée en obtenant la liste de tous les noms mais seulement lorsqu'ils correspondent à l'un des noms de la sous-requête (ce qui la limite aux noms qui ont le jaune).
  • Ceci est regroupé par nom et nous utilisons la fonction d'agrégat count pour combiner des lignes avec le même nom et nous donner le nombre de couleurs pour chaque nom.
  • Enfin, nous jetons ceux qui ont plus d'une couleur.

Je suppose ici que vous n'aurez pas une ligne dans la table avec un nom en double et couleur - en d'autres termes, vous devriez avoir une clé primaire ou toute autre contrainte (nom, couleur) . Si vous avez des doublons, la jointure croisée entraînera plus de lignes et vous devrez utiliser distinct ou group by dans la sous-requête).

4

Essayez ceci:

SELECT COUNT(NAME),NAME 
FROM SAMPLE 
GROUP BY NAME 
HAVING COUNT(*) = 1 AND MAX(COLOR) = 'yellow'; 

Comme @paxdiablo dit, vous devez laisser les lignes du groupe jusqu'à ce que après vous le groupe par, de sorte que le décompte exact. Ensuite, vous pouvez tester 'yellow' dans la clause HAVING.

Même s'il peut sembler redondant d'utiliser MAX() comme je l'ai fait dans l'exemple ci-dessus, c'est une bonne forme car toute expression de la clause HAVING doit utiliser des fonctions de groupe. HAVING limite les groupes alors que WHERE limite les lignes.

+0

Est-ce que le travail pour le rouge? On dirait que ça ne marchera que pour le jaune puisque c'est la couleur 'maximum'. – paxdiablo

+0

cela fonctionnera mais je pense que ce serait un peu plus clair si vous comptez (couleur) au lieu du nom - juste moi cependant. Cela fonctionne parce que COUNT (couleur) = 1 limite aux noms avec une seule couleur. – David

+1

Une autre requête appropriée pourrait être NOM SELECT DE SAMPLE GROUPE PAR NOM COUNT AYANT (*) = 1 ET COMPTE (CAS QUAND COULEUR = « JAUNE » ALORS 1 FIN) = 1 Cela permet des variations de la requête (par exemple pour choisir les personnes qui ont le jaune et une autre couleur). –

1

Une autre méthode utilisant une fonction analytique:

SELECT NAME 
FROM (
     SELECT NAME, 
       COLOR, 
       COUNT(*) OVER() ROWS_PER_NAME 
     FROM SAMPLE) 
WHERE COLOR = 'yellow' AND 
     ROWS_PER_NAME = 1 

En outre, si très peu de NAME avaient la couleur jaune, je voudrais essayer:

SELECT NAME, 
     COLOR 
FROM SAMPLE P 
WHERE COLOR = 'yellow' AND 
     NOT EXISTS (
      SELECT null 
      FROM SAMPLE C 
      WHERE C.NAME = P.NAME 
      AND COLOR != 'yellow') 
Questions connexes