Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/09/2011, 14h19   #1
Membre du Club
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 51
Points : 51
Par défaut Je n'arrive pas à trouver la bonne requête

Bonjour,

je cherche la bonne requête mysql qui permette de trouver les noms des catégories à condition que le nombre de marques différentes dans chacune de ces catégories soit supérieur ou égal à 3 et que le nombre de produits dans chacun de ces marques soit supérieur ou égal à 2.

D'abord je vous présente les 3 tables :

1) La table category (catégorie) qui a 2 colonnes :
- id_category : auto-increment
- name : varchar

Et voici les données :
Code :
1
2
3
4
5
id_category | name
----------------
1 | pull
2 | pantalon
3 | chaussure

2) La table manufacturer (marque) qui a 2 colonnes :
- id_manufacturer : auto-increment
- name : varchar

Et voici les données :
Code :
1
2
3
4
5
id_manufacturer | name
------------------------------------
1 | adidas
2 | nike
3 | puma
3) et la table product (produit) qui a 4 colonnes :
- id_product : auto-increment
- id_category : int
- id_manufacturer : int
- name : varchar

Et voici les données :
Code :
1
2
3
4
5
6
7
8
9
10
11
id_product | id_category | id_manufacturer | name
---------------------------------------------------------
1 | 1 | 1 | 1 | adidas pull rouge
2 | 1 | 1 | 1 | adidas pull vert
3 | 2 | 2 | 1 | adidas pantalon rouge
4 | 2 | 2 | 1 | adidas pantalon vert
5 | 2 | 2 | 2 | nike pantalon rouge
6 | 2 | 2 | 2 | nike pantalon vert
7 | 2 | 2 | 3 | puma pantalon rouge
8 | 2 | 2 | 3 | puma pantalon verte 
9 | 3 | 3 | 1 | adidas chaussure rouge
Donc la requête que je cherche doit m'afficher comme résultat la catégorie "pantalon", car d'après la table product, cette catégorie a 3 marques différentes (adidas, nike, puma) et que dans chacune de ces marques, il y a au moins 2 produits (pantalon rouge et pantalon vert pour adidas, pantalon rouge et pantalon vert pour nike, pantalon rouge et pantalon vert pour puma).

Avez-vous une idée ?

Merci d'avance pour vos réponses, cordialement
totoAussi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/09/2011, 15h43   #2
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Saluton,
Tu veux l'id_product, l'id_manufacturer, et l'id_category
Code mysql :
1
2
3
4
5
SELECT id_product, c.id-category, m.id_manufacturer
FROM product
INNER JOIN category c USING (id_product)
INNER JOIN manufacturer m USING (id_manufacturer)
GROUP BY id_product, c.id-category, m.id_manufacturer
Ensuite il te suffit de filtrer avec un clause HAVING
Code mysql :
1
2
HAVING COUNT(DISTINCT m.id_manufacturer) >= 2
AND COUNT(DISTINCT c.id_category)>=3
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/09/2011, 16h16   #3
Membre du Club
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 51
Points : 51
Bonjour,

merci pour ta réponse, mais ça ne marche pas.

Je sais que la requête qui permet d'avoir les noms de catégories qui ont plus de 3 marques différentes dans la table product est :


Code :
1
2
3
4
5
SELECT category.name 
FROM category, product
WHERE category.id_category = product.id_category 
GROUP BY id_category 
HAVING COUNT( DISTINCT id_manufacturer ) >3
Mais cette requête ne me dit pas si chacune des différentes marques des catégories trouvées a au moins 2 produits dans la table product.

Une idée ?

Merci d'avance, cordialement
totoAussi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/09/2011, 19h44   #4
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Alors il faut faire le comptage des id_manufacturer dans une sous-requêtes corrélée sur l'id_product et l'id_category.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 15h44   #5
Membre du Club
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 51
Points : 51
Rebonjour,

merci pour ta réponse, mais j'ai cherché à faire ce que tu m'as dit pendant des heures, mais j'ai pas réussi à trouver la requête miracle.

En tout cas j'ai 2 pistes :

1) Je sais que la requête qui permet d'avoir les noms de catégories qui ont plus de 3 marques différentes dans la table product est :

Code :
1
2
3
4
5
SELECT category.name 
FROM category, product
WHERE category.id_category = product.id_category 
GROUP BY id_category 
HAVING COUNT( DISTINCT id_manufacturer ) >3
Mais cette requête ne me dit pas si chacune des différentes marques des catégories trouvées a au moins 2 produits dans la table product.

2) et je sais que la requête qui permet d'avoir le nombre de marques différentes (manufacturer.name) d'une catégorie (id_category = 2 par exemple) qui ont au moins 2 produits dans la table product est :

Code :
1
2
3
4
5
6
7
8
 
 
SELECT COUNT(*) FROM (SELECT manufacturer.name
			FROM manufacturer, product
			WHERE manufacturer.id_manufacturer = product.id_manufacturer
			AND product.id_category =  '2'
			GROUP BY product.id_manufacturer
			HAVING COUNT( DISTINCT product.id_product ) >= 2)
Mais je ne parviens toujours pas à combiner les 2 requêtes.

J'ai essayé avec ça :

Code :
1
2
3
4
5
6
SELECT category.name, category.id_category, COUNT( DISTINCT id_manufacturer ) AS nombre_distinct_manufacturer, COUNT( DISTINCT id_product ) AS nombre_product
FROM category, product 
WHERE category.id_category = product.id_category 
GROUP BY product.id_category, product.id_manufacturer
HAVING nombre_distinct_manufacturer >3 
AND nombre_product >2
Mais je ne sais pas si c'est correct.

Une idée ?

Merci d'avance, cordialement.
totoAussi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h13   #6
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Dans la table product, est-ce que le trio id_product, id_category, id_manufacturer constitue un index UNIQUE ?
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h25   #7
Membre du Club
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 51
Points : 51
Bonjour,

non, seul id_product est unique car auto-incrémenté dans la table product.
id_category et id_manufacturer peuvent être présents en plusieurs fois dans la table product.

A+
totoAussi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h27   #8
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Bon en raisonnant correctement, , j'arrive à cette proposition de requête
Code mysql :
1
2
3
4
5
6
7
8
9
10
SELECT t1.produit
FROM ( SELECT id_produt, id_category
       FROM product
       GROUP BY id_produt, id_category
       HAVING COUNT(*) => 3) t1
INNER JOIN (SELECT id.product, id_category, ID_manufacturer
            FROM product
            GROUP BY  id.product, ID_manufacturer
            HAVING COUNT(*) => 2) t2
        USING (id_produt, id_category)
Mais j'intuite qu'elle n'est pas très logique parce que le deuxième GROUP BY ne porte pas sur l'ensemble des colonnes du SELECT. D'ailleurs d'autres SGBD que MYSQL n'accepterait pas cette syntaxe.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h32   #9
Membre du Club
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 51
Points : 51
Merci, je vais tester ça.

Je découvre maintenant que le language sql demande vraiment une logique pure.

Je te tiens courant
totoAussi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 16h35   #10
Membre du Club
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 51
Points : 51
Au fait, excuse moi,

à quoi correspond t1 et t2 svp ?

A+
totoAussi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 17h23   #11
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
Citation:
Envoyé par totoAussi Voir le message
Au fait, excuse moi,

à quoi correspond t1 et t2 svp ?

A+
Ce sont des alias pour les sous-requêtes, de manière à pouvoir les utiliser comme des tables temporaires dans la requête principale.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/09/2011, 17h29   #12
Membre du Club
 
Inscription : février 2009
Messages : 150
Détails du profil
Informations forums :
Inscription : février 2009
Messages : 150
Points : 51
Points : 51
Ok, merci.

Mais je crois que j'ai presque trouvé :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
 
SELECT category.name, category.id_category, 
(
	SELECT COUNT(*) FROM 
	(
			SELECT product.id_manufacturer 
			FROM product 
			GROUP BY product.id_manufacturer
			HAVING COUNT( DISTINCT product.id_product ) >= 2
	)
 
) AS nombre_distinct_manufacturer
FROM category, product
WHERE category.id_category = product.id_category 
GROUP BY product.id_category
HAVING nombre_distinct_manufacturer >= 3
Mais mysql m'affiche cette erreur :
Code :
1
2
 
Every derived TABLE must have its own alias
Une idée ?

Merci d'avance, cdt.
totoAussi est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/09/2011, 06h54   #13
Expert Confirmé
 
Avatar de Maljuna Kris
 
Homme Avcxjo MoKo
Retraité
Inscription : novembre 2005
Messages : 2 530
Détails du profil
Informations personnelles :
Nom : Homme Avcxjo MoKo
Âge : 60

Informations professionnelles :
Activité : Retraité
Secteur : Administration - Collectivité locale

Informations forums :
Inscription : novembre 2005
Messages : 2 530
Points : 3 523
Points : 3 523
La sous-sous-requête n'est pas aliassée.
Mais je doute que le résultat ait un sens, cette sous-sous-requête n'étant pas du tout corrélée.
__________________
Kie lumo eksistas ankaŭ ombro troviĝas. L.L. Zamenhof
articles : Comment émuler un tableau croisé [quasi] dynamique
et : Une énigme mathématique résolue avec MySQL
recommande l'utilisation de PDO (PHP5 Data Objects)
Maljuna Kris est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/09/2011, 12h33   #14
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 028
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 028
Points : 18 321
Points : 18 321
Envoyer un message via MSN à CinePhil
Citation:
trouver les noms des catégories à condition que le nombre de marques différentes dans chacune de ces catégories soit supérieur ou égal à 3
On va d'abord se contenter de l'identifiant de la catégorie.
Code :
1
2
3
4
SELECT id_category
FROM product
GROUP BY id_category
HAVING COUNT(DISTINCT id_manufacturer) > 2
Quelles sont ces marques ?
Code :
1
2
3
4
5
6
7
8
9
SELECT DISTINCT p.id_manufacturer
FROM product p
INNER JOIN
(
    SELECT id_category
    FROM product
    GROUP BY id_category
    HAVING COUNT(DISTINCT id_manufacturer) > 2
) t ON t.id_category = p.id_category
Parmi ces marques, quelles sont celles qui ont au moins deux produits ?
Code :
1
2
3
4
5
6
7
8
9
10
11
SELECT p.id_manufacturer
FROM product p
INNER JOIN
(
    SELECT id_category
    FROM product
    GROUP BY id_category
    HAVING COUNT(DISTINCT id_manufacturer) > 2
) t ON t.id_category = p.id_category
GROUP BY p.id_manufacturer
HAVING COUNT(p.id_product) > 1
Quels sont les produits de ces marques ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT p2.id_product
FROM product p2
INNER JOIN 
(
    SELECT p.id_manufacturer
    FROM product p
    INNER JOIN
    (
        SELECT id_category
        FROM product
        GROUP BY id_category
        HAVING COUNT(DISTINCT id_manufacturer) > 2
    ) t1 ON t1.id_category = p.id_category
    GROUP BY p.id_manufacturer
    HAVING COUNT(p.id_product) > 1
) t2 ON t2.id_manufacturer = p2.id_manufacturer
Quelles sont les catégories de ces produits ?
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SELECT DISTINCT c.name AS category_name
FROM category c
INNER JOIN product p3 ON p3.id_category = c.id_category
    INNER JOIN
    (
        SELECT p2.id_product
        FROM product p2
        INNER JOIN 
        (
            SELECT p.id_manufacturer
            FROM product p
            INNER JOIN
            (
                SELECT id_category
                FROM product
                GROUP BY id_category
                HAVING COUNT(DISTINCT id_manufacturer) > 2
            ) t1 ON t1.id_category = p.id_category
            GROUP BY p.id_manufacturer
            HAVING COUNT(p.id_product) > 1
        ) t2 ON t2.id_manufacturer = p2.id_manufacturer
    ) t3 ON t3.id_product = p3.id_product
C'est peut-être simplifiable en prenant le problème par l'autre bout mais j'ai faim !
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h08.


 
 
 
 
Partenaires

Hébergement Web