Comment l'utilisation réelle de nombre de ligne (COUNT(*)) dans la clause where sans écrire de la même requête que la sous-requête?

J'ai quelque chose comme ceci:

SELECT id, fruit, pip 
FROM   plant 
WHERE  COUNT(*) = 2;

Cette étrange requête est auto-explicatif, je suppose. COUNT(*) signifie ici le nombre de lignes dans plant table. Mon exigence est que j'ai besoin de récupérer des valeurs dans les champs spécifiés seulement si le nombre total de lignes dans la table = 2. Cela ne fonctionne pas, mais: invalid use of aggregate function COUNT.

Je ne peux pas faire ceci:

SELECT COUNT(*) as cnt, id, fruit, pip 
FROM   plant 
WHERE  cnt = 2;

d'une part, il limite le nombre de lignes de sortie à 1, et de deux, elle donne le même message d'erreur: invalid use of aggregate function.

Ce que je peux faire, c'est plutôt:

SELECT id, fruit, pip 
FROM   plant 
WHERE  (
        SELECT COUNT(*) 
        FROM   plant
       ) = 2;

Mais alors que la sous-requête est la principale requête ré-exécuter. Je vais présenter ici un petit exemple de la plus grande partie du problème, même si je sais supplémentaires COUNT(*) sous-requête dans l'exemple donné n'est pas un grand un rétroprojecteur.

Edit: je ne sais pas pourquoi la question est downvoted. Le COUNT(*) je suis en train d'essayer d'obtenir à partir d'une vue (une table temporaire) dans la requête, qui est une grande requête avec 5 à 6 jointures supplémentaires et les clauses where. Pour ré-exécuter la requête comme une sous-requête pour obtenir le nombre est inefficace, et je peux voir le goulot d'étranglement.

Voici la requête:

SELECT U.UserName, E.Title, AE.Mode, AE.AttemptNo, 
IF(AE.Completed = 1, 'Completed', 'Incomplete'), 
(
SELECT COUNT(DISTINCT(FK_QId)) 
FROM   attempt_question AS AQ
WHERE  FK_ExcAttemptId = @excAttemptId
) AS Inst_Count, 
(
SELECT    COUNT(DISTINCT(AQ.FK_QId)) 
FROM      attempt_question AS AQ
JOIN      `question` AS Q 
ON  Q.PK_Id = AQ.FK_QId                      
LEFT JOIN actions AS A                             
ON A.FK_QId = AQ.FK_QId
WHERE     AQ.FK_ExcAttemptId = @excAttemptId
AND (
Q.Type = @descQtn 
OR  Q.Type = @actQtn 
AND A.type = 'CTVI.NotImplemented'       
AND A.IsDelete = @status                 
AND (
SELECT COUNT(*) 
FROM   actions 
WHERE  FK_QId = A.FK_QId 
AND type != 'CTVI.NotImplemented'
AND IsDelete = @status
) = 0
)
) AS NotEvalInst_Count,  
(
SELECT COUNT(DISTINCT(FK_QId)) 
FROM   attempt_question AS AQ
WHERE  FK_ExcAttemptId = @excAttemptId 
AND Mark = @mark
) AS CorrectAns_Count, 
E.AllottedTime, AE.TimeTaken
FROM   attempt_exercise AS AE
JOIN   ctvi_exercise_tblexercise AS E 
ON AE.FK_EId = E.PK_EId
JOIN   ctvi_user_table AS U 
ON AE.FK_UId = U.PK_Id
JOIN   ctvi_grade AS G 
ON AE.FK_GId = G.PK_GId
WHERE  AE.PK_Id = @excAttemptId
-- AND COUNT(AE.*) = @number --the portion in contention.

De bien vouloir ignorer la requête ci-dessus et de me guider vers la droite en direction de la petite exemple de requête que j'ai posté, merci.

Ce n'est pas une surcharge à tous: si vous exécutez COUNT() contre une table entière, la plupart des moteurs (MySQL et PostgreSQL pour sûr, mais je pense que SQLite trop) de récupérer la table de cardinalité en O(1) à partir des métadonnées de la table. COUNT() devient un problème si vous l'exécutez avec un OÙ sur une clause de non indexées. Remplacement de la simple COUNT() avec une JOINTURE ou d'une autre "truc" pourrait même ralentir la requête.
MySQL n'est pas SqlLite
Lisez la dernière phrase de ma question. Avez-vous sérieusement pense que je vais simplement essayer d'obtenir le nombre à partir d'une table? La requête j'ai dans mon code est un peu complexe, avec 5 à 6 jointures et les clauses where. Pour la sous-requête, il n'est pas seulement peu élégante, mais très inefficace. En outre, je ne suis même pas de la récupération de la fonction count(*) valeur à partir d'une table, mais une situation temporaire dans la requête.
c'est vraiment pas, qui le dire? En attendant, ce qui est SqlLite? 😉
Le SELECT COUNT(*) FROM BaseTable va s'exécuter en O(1) seulement en MyISAM moteur de MySQL, pas en InnoDB. Et bien sûr, uniquement pour les tables de base, pas les vues ou les tables dérivées.

OriginalL'auteur nawfal | 2012-10-28