Aller au contenu

Limiter une requête sur le résultat d'un SUM


Sujets conseillés

Posté

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_Article
WHERE c.Id_Client = 123456
GROUP 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.

Posté

Essaye ça :

SELECT
c.Id_Client

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

(SUM(a.Id_Categorie IN (8,9)) >0)
AND
(SUM(a.Id_Categorie IN (10,4)) =0)
GROUP BY c.Id_Client

Posté (modifié)

Ou ça ;)

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
HAVING 'Recherche' > 0
AND 'Exclusion' = 0

On pense trop rarement au HAVING. Dis-nous ce que ça donne :)

Modifié par Vikchill
Posté

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 !

Posté

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' > 0
AND 'Exclusion' = 0

Posté

Reprise de la syntaxe de Robinson :

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
HAVING SUM(a.Id_Categorie IN (8,9)) > 0 AND SUM(a.Id_Categorie IN (10,4)) = 0

Posté (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é par Vikchill
Posté

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 ...

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...