2011-03-03 7 views
0

Premièrement, j'ai lu les articles avec les noms correspondants, et j'ai essayé d'intégrer certaines des solutions, mais je ne peux pas sembler obtenir cette requête SQL pour travailler ...Groupe invalide par fonction :: MySQL

le problème semble tourner autour de la fonction COUNT sur la ligne 8.

ici, il est ..


SELECT `purchase_orders`.`purchase_order_id`,`purchase_orders`.`sequence_id`,`purchase_orders`.`order_number`,`vendors`.`name`,`purchase_orders`.`date`,COUNT(`purchase_order_items`.`purchase_order_id`) `item_count`,`purchase_orders`.`total_value`,`purchase_orders`.`status`,`users`.`first` 
FROM (`purchase_orders`, `vendors`, `purchase_order_items`,`users`) 
WHERE `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`purchase_order_id` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`sequence_id` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`order_number` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `vendors`.`name` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`date` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND COUNT(`purchase_order_items`.`purchase_order_id`) LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`total_value` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `purchase_orders`.`status` LIKE '%122%' 
OR `purchase_orders`.`aid`='c4ca4238a0b923820dcc509a6f75849b'AND`purchase_orders`.`vendor_id`=`vendors`.`vid`AND`purchase_orders`.`created_by`=`users`.`uid`AND`purchase_order_items`.`purchase_order_id`=`purchase_orders`.`purchase_order_id` AND `users`.`first` LIKE '%122%' 
GROUP BY `purchase_orders`.`purchase_order_id` 
ORDER BY `purchase_orders`.`purchase_order_id` ASC 
LIMIT 0,1 

Répondre

1

Lorsque vous utilisez COUNT(xxx) dans un SQL, vous devez l'utiliser dans la clause HAVING:

par exemple.

HAVING COUNT(xxx) > yyyy 

De même, généralement, vous souhaitez GROUP BY les champs sur lesquels vous n'utilisez pas de fonctions d'agrégation. Par exemple:

SELECT person_name 
    , SUM(bonuses) 
    FROM person x 
    , person_bonus y 
WHERE x.person_id = y.person_id 
GROUPE

PAR person_name

Comme j'ajouter des colonnes supplémentaires à cette instruction SELECT, je dois soit les utiliser une autre fonction d'agrégation (COUNT, SUM, etc.), ou je dois GROUPE PAR eux.

Et encore une fois, tout ce que vous utilisez une fonction d'agrégation sur peut être utilisé dans votre HAVING:

SELECT person_name 
     , SUM(bonuses) 
     FROM person x 
     , person_bonus y 
    WHERE x.person_id = y.person_id 
    GROUP BY person_name 
    HAVING SUM(bonuses) > 50000 // I wish :) 
+0

Essayer cela .... – Peter

0

Règles d'utilisation clause GROUP BY:

  1. La colonne que vous GROUP BY doit être également dans votre instruction SELECT.
  2. N'oubliez pas de grouper par la colonne sur laquelle vous voulez des informations et non celle sur laquelle vous appliquez la fonction d'agrégat.

En vous par exemple, vous archivez pour purchase_order_items.purchase_order_id = purchase_orders.purchase_order_id et vous êtes également l'application d'une fonction d'agrégation COUNT (purchase_order_items.purchase_order_id)

+0

http://dev.mysql.com/doc/refman/5.0/fr/order-by-optimization.html Nous pouvons utiliser – Raja

1

Même si vous avez sélectionné une solution à votre question, Cependant, votre requête est vraiment sale. La prémisse de SQL est d'identifier les relations une fois sur la façon dont la table se rapporte à des clés données et d'appliquer les filtres EXTRA dans l'où. Votre requête comportait plusieurs fois "OU". Voici une version plus propre de votre requête. Notez que la clause where a la clé "aide" que vous cherchiez, et une seule clause AND pour rejoindre les tables ... Sous la requête sont les clauses AND restantes où vous avez eu tant d'éléments avec LIKE '% 122%' un COUNT (de n'importe quoi) retournerait un nombre.

SELECT 
     po.purchase_order_id, 
     po.sequence_id, 
     po.order_number, 
     v.name, 
     po.date, 
     COUNT(poi.purchase_order_id) item_count, 
     po.total_value, 
     po.status, 
     users.first 
    FROM 
     purchase_orders po, 
     vendors v, 
     purchase_order_items poi, 
     users 
    WHERE 
      po.aid = 'c4ca4238a0b923820dcc509a6f75849b' 
     AND po.vendor_id = v.vid 
     AND po.purchase_order_id = poi.purchase_order_id 
     AND po.created_by = users.uid 
    GROUP BY 
     po.purchase_order_id 
    ORDER BY 
     po.purchase_order_id 
    LIMIT 
     0, 1 

Ces je ne comprenais pas ce que vous recherchez, mais je finir par être après tous les autres clauses WHERE j'ai eu ci-dessus ... Encore une fois, le comte (poi.purchase_order_id) LIKE « % 122% Je ne pense pas est applicable. Probablement les autres colonnes basées sur "ID" que je suppose sont basées numériques.

 AND po.purchase_order_id LIKE '%122%' 
     AND po.sequence_id LIKE '%122%' 
     AND po.order_number LIKE '%122%' 
     AND v.name LIKE '%122%' 
     AND po.date LIKE '%122%' 
     AND COUNT(poi.purchase_order_id) LIKE '%122%' 
     AND po.total_value LIKE '%122%' 
     AND po.status LIKE '%122%' 
     AND users.first LIKE '%122%' 

Il est apparu que vous vouliez appliquer toutes les conditions de jointure pour chaque instance, mais aurait dû - des éclaircissements

where 
    (all first group of conditions) 
    OR (all next group of conditions) 
    OR (all next, etc) 

J'espère que cela aide à clarifier la façon dont l'interrogation est structuré.

+0

Merci pour l'explication détaillée et des exemples. Mais c'est un peu plus compliqué qu'il n'y paraît au départ. Cette requête est générée à partir d'une autre requête qui est analysée puis reconstruite avec toutes les options définies par l'utilisateur .. comme les mots-clés de recherche, ordre de tri, limite, pagination .. Voici ce que je fais .. http://datatables.dyndns-web.com/main/basic#TheSQL – Peter

+1

@Peter, oui, mais à partir de ce qui est en cours de construction, vous devriez toujours avoir une requête CORE pour les relations, et seulement virer sur les composants WHERE supplémentaires. Comme vous pouvez le voir dans mon exemple, ils n'ont pas besoin d'être répétés, ni ouverts pour des conditions "OU" permettant de plus gros problèmes. – DRapp

+0

Merci, je vais essayer de refactoriser cette chose pour construire de meilleures requêtes et Ill def utiliser vos exemples. – Peter