2009-11-23 6 views
0
SELECT 
    (SELECT 
     SUM(IF(status = 'Active', 1, 0)) AS `univ_active`, 
     SUM(IF(status = 'Inactive', 1, 0)) AS 'univ_inactive', 
     Count(*) 
    FROM online_university 
) 
AS tot_university, 
(SELECT 
    SUM(IF(status = 'Active', 1,0)) AS `user_active`, 
    SUM(IF(status = 'Inactive', 1,0)) AS 'user_inactive' 
    Count(*) 
    FROM online_register_user) 
AS tot_users 

Résultat doit êtreQuel est le problème dans ma requête MYSQL?

univ_active=4 univ_inactive=2 tot_university=6 
user_active=10 user_inactive=3 tot_users = 13 

Comment puis-je obtenir? La requête ci-dessus renvoie ERROR: L'opérande doit contenir 1 colonne (s)

Cela permet de préparer un rapport pour un projet à partir de toutes les tables retournant les enregistrements actifs, inactifs et totaux de la table. Si cette méthode est fausse alors que dois-je utiliser? Toute suggestion.

Répondre

3

Les sous-requêtes ne peuvent renvoyer qu'une colonne. Vous devez effectuer plusieurs sous-requêtes, une jointure ou un hack de concatation bon marché (CONCAT_WS(',', SUM(IF(status = 'Active', 1,0)), SUM(IF(status = 'Inactive', 1,0))) dans une seule sous-requête.

+0

Merci, il fonctionne très bien – sathish

1

Par la mise en page de la requête comme je viens à la question, il devient très évident que le tot_university alias, par exemple serait associé à deux colonnes, ce qui est impossible ...

En dehors de cette syntaxe/erreur logique, l'ensemble de la requête semble mal structuré pour produire le résultat souhaité.

Cela ressemble beaucoup à des devoirs, ou un apprentissage auto-assigné, donc je ne vais pas gâcher avec une requête prête à l'emploi, à la place voici quelques conseils.

  • l'information provient de deux volets distincts, tables non liées, peut-être utiliser UNION pour obtenir des résultats en une seule requête (lors de l'exécution efficace deux requêtes) (vous pouvez ensuite utiliser une colonne supplémentaire avec un texte comme « Univ », ' Public 'pour différencier les deux lignes)
  • la somme (colonne IF = x, 1,0) est une bonne astuce pour compter des valeurs particulières, sans avoir à faire un groupe par, essentiellement "enrouler" les comptes en une étape . L'astuce concat() est bonne si vous vous concentrez exclusivement sur les résultats de type textuel, par exemple pour écrire, tel quel, dans un rapport, sinon, il serait préférable de conserver les résultats dans des colonnes séparées, pour un traitement ultérieur , affichage dans les tableaux etc ...
+0

oui je l'ai fait mal dans ma requête, je vous remercie de votre explication – sathish

1

Comme BipedalShark a dit, vos requêtes devraient avoir 1 colonne et ils en ont 2 maintenant. Mais à part cela, vous devriez penser à utiliser count (*) et where clause. Il doit donc être lissée comme ceci:

select 
(select count(*) from online_university where status = 'Active') as univ_active, 
(select count(*) from online_university where status = 'Inactive') as univ_inactive, 
(select count(*) from online_register_user where status = 'Active') as user_active, 
(select count(*) from online_register_user where status = 'Active') as user_inactive 
+0

bonne idée, j'ai un doute? Cela prendra-t-il trop de temps pour s'exécuter? – sathish

+0

Ça ne prendra pas grand-chose. Count() fonctionne très vite, esp. si vous avez des indices sur les champs d'état. – Vitaly

2

Comme l'erreur dit, vous êtes la sélection d'un sous-requête qui renvoie deux colonnes.

SELECT (one_thing, another_thing) AS combined_thing 

n'existe pas dans SQL. Vous devez mettre chaque sous-requête lui-même:

SELECT (
    SELECT SUM(IF(status='Active', 1, 0)) FROM online_university 
) AS univ_active, (
    SELECT SUM(IF(status='Inactive', 1, 0)) FROM online_university 
) AS univ_inactive, (
    SELECT SUM(IF(status='Active' OR status='Inactive', 1, 0)) FROM online_university 
) AS tot_university, (
    SELECT SUM(IF(status='Active', 1, 0)) FROM online_register_user 
) AS user_active, (
    -- and so on 

Cependant, il n'y a vraiment aucun avantage à faire tout cela en une seule requête. Beaucoup plus facile à dire:

SELECT COUNT(*) FROM online_university WHERE status='Active'; -- univ_active 
SELECT COUNT(*) FROM online_university WHERE status='Inactive'; -- univ_inactive 
SELECT COUNT(*) FROM online_university; -- tot_university 
SELECT COUNT(*) FROM online_register_user WHERE status='Active'; -- user_active 
    -- and so on 

puis de présenter ces résultats ensemble dans la couche d'application. Une clause WHERE est plus rapide et peut utiliser des index appropriés qu'une expression calculée comme SUM/IF ne peut pas.

encore plus simple:

SELECT status, COUNT(*) FROM online_university GROUP BY status; 
SELECT status, COUNT(*) FROM online_register_user GROUP BY status; 
Questions connexes