Forum Programmation.php mysql et requetes imbriques

Posté par .
Tags : aucun
0
10
nov.
2004
Bonjour,

J'ai un petit souci avec mysql. J'ai trois tables :
Produit avec Prod_ID et Prod_Nom
Societe avec Societe_ID et Societe_Nom
Et une table SocieteProd qui permet de savoir quel société a quel produit.
SocieteProd :
SocieteProd_ID
Produit_ID
Societe_ID

Mon programme (en php) permet d'attribuer un ou plusieurs produits à une société. Ce que j'aimerais faire, c'est que lorsque l'utilisateur ajoute un produit, seul les produits que la société ne possède pas soient présentés dans la liste. J'avais donc pensé à une requete imbriqué du style :

SELECT Prod_Nom FROM Produit WHERE Prod_ID NOT IN (SELECT Prod_ID FROM SocieteProd WHERE SocieteID = $societe_id)

Le Pb c'est que ça ne fonctionne pas sous mysql ! mysql ne sais apparemment pas gérer les requetes imbriqués....

Ma question est donc la suivante : Est-ce possible de réaliser ce type de requete uniquement avec des jointures (LEFT JOIN etc...)???
Sinon voyez vous une autre solution ??
  • # Re:

    Posté par . Évalué à 2.

    Depuis le temps qu'on dit qu'il faut utiliser PostgreSQL...

    Sinon, ton problème tu dois pouvoir le faire.

    Avec php tu récupères la liste des Prod_ID avec la requête "SELECT Prod_ID FROM SocieteProd WHERE SocieteID != $societe_id".

    Puis tu reconstruis une autre requête avec
    - "SELECT Prod_Nom FROM Produit WHERE Prod_ID != val1 AND Prod_ID != val2 Prod_ID != val3 AND ..."

    C'est chiant à faire mais ça se fait.
  • # EXCEPT ?

    Posté par . Évalué à 2.

    Hello,

    Je ne sais pas si MySQL (dans la version que tu utilises) gère le mot clé EXCEPT (en fait j'utilise PostgreSQL), mais tu peux toujours essayer un:

    SELECT prod_id FROM produit EXCEPT SELECT prod_id FROM societeprod WHERE societeid=$societe_id; (1)

    Avec cette requête on devrait donc obtenir les identifiants des produits uniquement.
    Je suppose donc qu'il faudrait faire une jointure du style

    SELECT P.prod_nom
    FROM produit AS P,
    (SELECT prod_id FROM produit EXCEPT SELECT prod_id FROM societeprod WHERE societeid=$societe_id) AS P1
    WHERE P.prod_id=P1.prod_id;

    Cela dit, si ça ne gère pas non plus la sous-requête de cette forme, ce n'est pas mieux comme proposition.

    Donc si tu veux uniquement les noms de produits en une seule requête "simple", il suffirait de remplacer prod_id par pro_nom dans (1) mais cela pourrait poser des problèmes de performances si les tables ont de très nombreux enregistrement et/ou si cette requête est très souvent utilisée !

    Je suis peut-être aussi totalement à côté de la plaque (ça m'arrive ... assez souvent !).
  • # NOT EXISTS

    Posté par . Évalué à 2.

    Bonsoir,
    Tu devrais pouvoir récupérer les Prod_ID de la manière suivante :

    SELECT Prod_ID FROM Produit WHERE NOT EXISTS (SELECT * FROM SocieteProd WHERE SocieteID = $societe_id)

    Je te laisse l'adapter pour récupérer le nom du produit.

    Sinon, un peu de doc MySQL ne fait jamais de mal : http://www.nexen.net/docs/mysql/(...)

    Bon courage
    • [^] # Re: NOT EXISTS

      Posté par . Évalué à 1.

      Le probleme c'est que c'est une requete imbrique
      SELECT Prod_ID FROM Produit WHERE NOT EXISTS (SELECT Prod_ID FROM SocieteProd); (pour simplifier) me retourne :
      ERROR 1064: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXISTS (SELECT Prod_ID FROM SocieteProd)' at line 1

      Ca revient au même que NOT IN
      As tu reussis à faire fonctionner une requette de ce style SOUS MYSQL ??

      sinon, je pense que je vais suivre l'avis de 007 et idiotduvillage ;) et m'orienter plutot vers une base postgre...

      Merci en tous cas pour vos réponces...
    • [^] # Re: NOT EXISTS

      Posté par . Évalué à 1.

      Et ca, ca ne marcherait pas ???

      SELECT Produit.Prod_Nom FROM Produit, SocieteProd WHERE Produit.Prod_ID= SocieteProd.Produit_ID and SocieteProd <> "$societe_id"

      A priori, ca prend bien tous les produits, sauf ceux que fait la société, non ?
      Enfin, ceci dit, la version stable 4.1 vient de sortir, ca serait dommage de s'en priver :)

      Sinon, dans le même genre, il y a ca dans la doc MySQL :

      Sometimes you want to retrieve the records that DONT match a select statement.

      Consider this select:
      SELECT CarIndex FROM DealerCatalog, BigCatalog WHERE
      DealerCatalog.CarIndex=BigCatalog.CarIndex

      This finds all the CarIndex values in the Dealer's catalog that are in the bigger distributor catalog.


      How do I then find the dealer CarIndex values that ARE NOT in the bigger catalog?

      The answer is to use LEFT JOIN - anything that doesn't join is given a NULL value , so we look for that:

      SELECT CarIndex FROM DealerCatalog LEFT JOIN BigCatalog ON DealerCatalog.CarIndex=BigCatalog.CarIndex WHERE BigCatalog.CarIndex IS NULL

      http://dev.mysql.com/doc/mysql/fr/SELECT.html(...)

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.