2010-11-24 7 views
0

j'ai défini la requête suivante:Pourquoi quelque chose comme select ne compte pas ((sélectionnez * chez les producteurs)) auprès des producteurs; travail?

select count((select * from producers)) from producers; 

En supposant une table producers avec 3 colonnes (A, B et C) et 2 rangs:

A B C 
----- 
0 1 2 
3 4 5 

je vous attendez la sortie suivante:

2 
2 

Cela ne fonctionne pas. Alors que la requête elle-même est fondamentalement inutile (même si cela fonctionnait, cela ne donnerait aucun résultat utile), j'aimerais essayer de comprendre pourquoi cela ne fonctionne pas.

(select * from producers) 

Cela donne une liste de lignes avec des informations sur tous les attributs sur la table producers.

select count((select * from producers)) from producers; 

celui-ci pour chaque ligne sur producers, montrent le nombre 2 (le nombre d'éléments dans producers).

Pourquoi ça ne marche pas? Limitation SQL? Y a-t-il quelque chose qui ne va pas dans la logique que je suis ici?

Merci

Répondre

3

C'est une limitation de SQL, autant que je sache. Les sous-requêtes ne sont pas autorisées dans l'expression COUNT. Evidemment (select * from producers) est une sous-requête, donc ce n'est pas autorisé là.

Je pense que votre malentendu est que vous pensez que vous appelez la fonction comme COUNT(SELECT * FROM producers) alors que dans SQL, c'est comme SELECT COUNT(*) FROM producers.

Fonctions comme MAX, MIN, SUM et COUNT sont globales fonctions, ce qui signifie qu'ils prennent un argument scalaire mais exécuter une fois pour chaque ligne, accumulant les résultats chaque itération.Donc, SELECT MAX(column) FROM table exécute la fonction MAX une fois pour chaque ligne dans table, alors que vous pourriez penser que MAX s'exécute une fois et est passé à chaque ligne dans table.

contraste avec des opérateurs tels que IN, EXISTS, ANY et ALL, qui ont une sous-requête comme argument. Ils sont effectivement passés tous les résultats de leur sous-requête chaque fois qu'ils sont invoqués.

+1

Ce n'est pas une limitation. C'est une logique de fonction. La fonction 'COUNT()' accepte une valeur. – zerkms

+0

Mais une valeur de ce "type"? Il doit accepter quelque chose en tant que tableau? –

+0

@devoured elysium: où avez-vous vu 'array' dans votre requête? C'est juste un ensemble d'enregistrements. Et 'COUNT' attend une valeur scalaire. – zerkms

0

Le mot clé Count est pour compter les lignes de données non colonnes de données.

Vous auriez besoin d'interroger les métadonnées pour obtenir le nombre de colonnes dans une table, bien sûr que la requête pour faire cela sera spécifique à la plate-forme de base de données.

+0

Je n'ai pas dit (ou laissé entendre) n'importe quelle définition de Count autre que celle que vous avez donnée, je crois. –

1

COUNT() La fonction attend une seule valeur.

Cela renvoie ce que vous voulez:

SELECT COUNT(*) 
     FROM producers p1 
CROSS JOIN producers p2 
    GROUP BY p1.A 
+0

Pourquoi voudriez-vous 'INNER JOIN ON 1 = 1' quand vous pourriez faire' CROSS JOIN' ou simplement 'FROM PRODUCTS p1, producteurs p2'? – Gabe

+0

Pourquoi Count() attend seulement une valeur? Count() ne prend-il pas en entrée un ensemble de lignes? Ma question ici est plus axée sur essayer de comprendre pourquoi Count() ne permet pas une requête à l'intérieur, pas sur la façon d'obtenir une sortie similaire à la requête que j'ai faite. –

+0

"Pourquoi Count() n'attend-il qu'une valeur? Count() ne prend-il pas en entrée un ensemble de lignes?" - parce que c'est le cas. Par définition. Il accepte une valeur. – zerkms

3

Il devrait juste être

Select count(1) from producers; 

Si vous demandez au sujet sélectionne interne, puis la sélection intérieure doit faire partie de la clause FROM, par exemple

Select count(1) from (select * from producers) 

Les deux font la même chose mais la première est plus efficace.

+1

" Les deux font la même chose mais le premier est plus efficace. " - C'est le même plan d'exécution pour les deux requêtes. Donc, les deux ont la même performance. – zerkms

+0

merci !!! juste ce dont j'avais besoin aujourd'hui (numéro 2 qui est). – Keng

0

"Pourquoi ne COUNT() attendre qu'une valeur? Ne comptez pas() prend en entrée un ensemble de lignes?"

comte accepte une expression. Si l'expression est nulle, elle n'est pas comptée. Sinon, c'est.

Si une table comporte cinq lignes et qu'une colonne a trois valeurs réelles et deux valeurs NULL, un comptage de cette colonne renvoie trois lignes.

ID Colour Size 
1 Red  30 
2 Blue <null> 
3 <null> 20 
4 <null> <null> 
5 Blue 10 

SELECT COUNT (COULEUR), COUNT (TAILLE) donnerait 3 et 3.

COUNT (*) est spécial en ce qu'il donne le nombre de lignes dans le tableau, quelles que soient les valeurs NULL. COUNT ne peut pas/ne fonctionnera pas (sélectionner * from producer) ou même (1,3) car ce ne sont pas des expressions qui peuvent être interprétées comme nulles ou non nulles.

Questions connexes