captain_torche Posté 21 Septembre 2006 Posté 21 Septembre 2006 Bonjour, Je suis (encore) dans des scripts de stats compliqués, qui me poussent aux limites de mes connaissances en SQL. Je dois trouver le nombre de clients ayant au moins l'un des produits d'une liste x dans la totalité de leurs commandes, mais n'ayant jamais commandé un produit dans la liste y Les tables de la base sont du genre : CLIENT | COMMANDE | PRODUIT | ARTICLE Sachant qu'un client a X commandes, qu'une commande peut comporter Y produits, et que les produits sont liés aux articles par l'id de l'article. J'avais tenté de faire comme suit, mais ça ne fonctionne pas (pourtant, je pense approcher du but) SELECT c.Id_Client, SUM(a.Id_Categorie IN (8,9)) AS 'Recherche', SUM(a.Id_Categorie IN (10,4)) AS 'Exclusion'FROM Commandes c INNER JOIN Produit p ON p.Id_Commande = c.Id_Commande INNER JOIN Article a ON a.Id_Article = p.Id_ArticleWHERE c.Id_Client = 123456GROUP BY c.Id_Client J'ai volontairement limité la requête à un client pour les tests, où je sais qu'il a commandé les catégories de produits 9 et 16 uniquement. La colonne 'Recherche' me sort 5 comme résultat (le client a 5 produits de la catégorie 9), et la colonne 'Exclusion' me sort 0 (il n'a aucun produit des catégories 10 et 4) Si je veux valider cette requête, je pensais qu'il me suffirait d'ajouter au WHERE les conditions suivantes : AND 'Recherche' > 0 AND 'Exclusion' = 0 Malheureusement, si je les rajoute, le résultat ne ressort plus. Après quelques tests, il s'avère que le résultat sort si je vérifie que les deux critères sont égaux à zéro, quelles que soient les valeurs des colonnes associées : AND 'Recherche' =0 AND 'Exclusion' = 0 Est-il possible que le calcul des résultats du SUM ne se fasse qu'après le reste des vérifications ? Et dans ce cas, comment faire ? Merci d'avance.
robinsonvendredi Posté 21 Septembre 2006 Posté 21 Septembre 2006 Essaye ça : SELECTc.Id_ClientFROM Commandes cINNER JOIN Produit p ON p.Id_Commande = c.Id_CommandeINNER JOIN Article a ON a.Id_Article = p.Id_ArticleWHERE (SUM(a.Id_Categorie IN (8,9)) >0)AND(SUM(a.Id_Categorie IN (10,4)) =0)GROUP BY c.Id_Client
Vikchill Posté 21 Septembre 2006 Posté 21 Septembre 2006 (modifié) Ou ça SELECTc.Id_Client,SUM(a.Id_Categorie IN (8,9)) AS 'Recherche',SUM(a.Id_Categorie IN (10,4)) AS 'Exclusion'FROM Commandes cINNER JOIN Produit p ON p.Id_Commande = c.Id_CommandeINNER JOIN Article a ON a.Id_Article = p.Id_ArticleWHERE c.Id_Client = 123456GROUP BY c.Id_ClientHAVING 'Recherche' > 0 AND 'Exclusion' = 0 On pense trop rarement au HAVING. Dis-nous ce que ça donne Modifié 21 Septembre 2006 par Vikchill
captain_torche Posté 21 Septembre 2006 Auteur Posté 21 Septembre 2006 Non, malheureusement, ça ne fonctionne pas La proposition de robinsonvendredi aboutit sur une erreur "Invalid use of group function", alors que celle de Vikchill ne change rien au problème de départ : il n'arrive pas à "lire" le contenu des colonnes, et considère toujours ce contenu égal à zéro. Mais merci beaucoup de vous être penchés dessus !
Vikchill Posté 21 Septembre 2006 Posté 21 Septembre 2006 blblblbl J'arrive pas à comprendre pourquoi le HAVING marche pas Et un SELECT sur le SELECT? SELECT *FROM (SELECT c.Id_Client, SUM(a.Id_Categorie IN (8,9)) AS 'Recherche', SUM(a.Id_Categorie IN (10,4)) AS 'Exclusion' FROM Commandes c INNER JOIN Produit p ON p.Id_Commande = c.Id_Commande INNER JOIN Article a ON a.Id_Article = p.Id_Article WHERE c.Id_Client = 123456 GROUP BY c.Id_Client)WHERE 'Recherche' > 0AND 'Exclusion' = 0
captain_torche Posté 21 Septembre 2006 Auteur Posté 21 Septembre 2006 Non, malheureusement, on a une vieille version de MySQL sur le serveur, les requêtes imbriquées ne fonctionneront pas.
Portekoi Posté 21 Septembre 2006 Posté 21 Septembre 2006 Reprise de la syntaxe de Robinson : SELECTc.Id_Client,SUM(a.Id_Categorie IN (8,9)) AS 'Recherche',SUM(a.Id_Categorie IN (10,4)) AS 'Exclusion'FROM Commandes cINNER JOIN Produit p ON p.Id_Commande = c.Id_CommandeINNER JOIN Article a ON a.Id_Article = p.Id_ArticleWHERE c.Id_Client = 123456GROUP BY c.Id_ClientHAVING SUM(a.Id_Categorie IN (8,9)) > 0 AND SUM(a.Id_Categorie IN (10,4)) = 0
Vikchill Posté 21 Septembre 2006 Posté 21 Septembre 2006 (modifié) Ah bah oui c'était peut-être simplement les alias qu'il n'aimait pas, cette requête a plus de chance de fonctionner. Sinon, passer par une vue au lieu d'une requête imbriquée, mais je sais pas si MySQL gère les vues, et ça devient très "bidouille". Modifié 21 Septembre 2006 par Vikchill
captain_torche Posté 21 Septembre 2006 Auteur Posté 21 Septembre 2006 Portekoi, tu es un chef, ça a l'air de très bien fonctionner. Bon, maintenant faut que je la lance sur une table de deux millions d'enregistrements, en espérant qu'elle tienne le coup ...
Portekoi Posté 21 Septembre 2006 Posté 21 Septembre 2006 Utilise le 'LIMIT' (0, 10000) puis (100000, 20000) etc... si ca plante
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant