IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PHP & Base de données Discussion :

[SQL] Pb conditions sur tables multiples


Sujet :

PHP & Base de données

  1. #1
    Membre expérimenté
    Avatar de guitou12
    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 077
    Points : 1 561
    Points
    1 561
    Par défaut [SQL] Pb conditions sur tables multiples
    Bonjour, j'ai un petit de souci de requête comme vous pouviez vous en douter.

    Voilà le schéma simplifié de mes tables.
    Table user : nom,prenom,iduser

    Table groupe : idgroupe, nom

    Table messages : idmess, iduser, idgroupe, texte


    Sachant qu'un message peut être adressé SOIT à un user (iduser != -1 et idgroupe = -1) SOIT à un groupe (idgroupe != -1 et iduser = -1) je cherche à récupérer suivant les cas

    -> Le nom du groupe (si c'est destiné au groupe)
    ou bien
    -> Les noms et prénoms de l'utilisateur (si c'est destiné à l'utilisateur)

    J'ai tenté avec un case mais sans succès....

    Un coup de main serait le bienvenue,

    en vous remerciant par avance.
    Ex développeur Php / J2EE.
    Actuellement reconverti à SharePoint 2013

    Mon blog SP 2013

  2. #2
    Membre confirmé
    Avatar de DBProg
    Profil pro
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 242
    Points : 579
    Points
    579
    Par défaut
    Salut !

    Je te propose une solution qui fonctionne, mais elle n'est pas très optimisée (du moins je pense). Je suis également ouvert à toute optimisation, je ne connais pas trop les CASE en SQL encore.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT M.idmess, M.texte, IF(M.iduser IS NULL, (
    SELECT idgroupe, nom FROM groupe G WHERE G.idgroupe = M.idgroupe),
    (SELECT iduser, nom, prenom FROM user U WHERE U.iduser = M.iduser))
    FROM messages M
    Comme tu peux le constater j'ai utilisé IS NULL pour la condition. Car en fait je te conseille de mettre l'une des deux valeurs (celle qui n'est pas renseignée) à NULL et non à -1. C'est plus propre, et c'est fait pour !
    La vitesse de la lumière étant supérieure à la vitesse du son, certaines personnes brillent encore tant qu'elles n'ont pas parlé
    -----------------------------------------------------------
    Retrouvez mes articles informatique sur mon Site Developpez.
    Le reste, sur le Site perso !


  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 102
    Points : 120
    Points
    120
    Par défaut
    Re-salut :-)

    un UNION me semble tout indiqué.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT nom, prenom, texte FROM messages JOIN user USING(iduser)
    UNION
    SELECT nom, '/' as 'prenom', texte FROM messages JOIN groupe USING(idgroupe)
    remarque que je triche un peu pour le groupe en créant un pseudo champ prenom dans la requete (je mets arbitrairement la valeur "/") afin de calquer la structure de cette requete sur la premiere pour que le UNION marche.


    Si tu peux créer à la volée pour chaque ligne l'info type de destinataire en créant également le pseudoi champ 'type_detin'
    remarque que structurellement parlant, les différentes requetes qui composent le UNION doivent rester "superposables" (même champs et dans le même ordre):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT 'Utilisateur' AS 'type_dest', 'nom, prenom, texte FROM messages JOIN user USING(iduser)
    UNION
    SELECT 'Groupe' AS 'type_dest', nom, '/' as 'prenom', texte FROM messages JOIN groupe USING(idgroupe)
    Bon et le fin du fin, si tu veux garder la possibilité de brasser, ordonner, grouper etc. les resultats dans leur globalité (par ex pas de clause order pour UNION), et si ton serveur SQL est > 4.1 (je te guarantie rien pour les versions plus anciennes)
    Tu peux faire comme si cette requete audessus était une table que tu peux manipuler (classer par nom par exemple) en fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT type_dest, nom, prenom, texte FROM
    (
    SELECT 'Utilisateur' AS 'type_dest', nom, prenom, texte FROM messages JOIN user USING(iduser)
    UNION
    SELECT 'Groupe' AS 'type_dest', nom, '/' as 'prenom', texte FROM messages JOIN groupe USING(idgroupe)
    ) AS DERIVED_TABLE
    ORDER BY nom
    sans aller jusqu'a la sophistication de la dernière pense toujours a ca : les requetes (autant que tu veux en fait) reliées par un UNION doivent être toutes superposables en structures.


    Table user : nom,prenom,iduser

    Table groupe : idgroupe, nom

    Table messages : idmess, iduser, idgroupe, texte
    il n'y a pas de sotte existence

  4. #4
    Membre expérimenté
    Avatar de guitou12
    Homme Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 077
    Points : 1 561
    Points
    1 561
    Par défaut
    Alors une petite précision pour rajouter un peu de piment (sinon c'est définitivement pas marrant hein )

    Je ne peux pas mettre mes champs à NULL étant donné que c'est une base utilisée par un soft et que celui qui en a fait la conception devait pas être bien réveillé ce jour là. Donc en résumé TOUS les champs doivent être remplis alors pour gruger ils calent des espaces dans les champs qui ne contienent rien.

    Ensuite pour la version SQL>4.1 aucune idée étant donné que je suis sous Oracle8i

    Je vais tester avec la version de Gisele mais il faut que j'arrive à tout piger

    EDIT : j'ai testé et ... ça ne fonctionne pas

    Voilà ma requête (inspirée de la 1ère de gisele) avec les vrais noms de champs (attention ça fait mal aux yeux)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     SELECT 
    USR_0,  // iduser (table AUTILIS & XMESSAGES) --> -1 ou valeur
    NOMUSR_0, // nom (table AUTILIS)
    PRENOMUSR_0,  // prenom (table AUTILIS)
    XCHRONO_0, // index message (table XMESSAGE)
    TEXTE_0, // texte message (table XMESSAGE)
    GROUPE_0, // groupe destinataire (table XMESSAGE) --> -1 ou valeur
    INTITDROIT_0 // nom du groupe (table XDROITS)
       FROM XMESSAGES JOIN AUTILIS USING(USR_0)
    WHERE XCHRONO_0=1
    UNION 
      SELECT 
    USR_0, 
    NOMUSR_0, 
    '/' AS 'PRENOMUSR_0', 
    XCHRONO_0, 
    TEXTE_0, 
    GROUPE_0, 
    INTITDROIT_0 
      FROM XMESSAGES JOIN XDROITS USING (GROUPE_0)
    WHERE XCHRONO_0=1
    J'ai pas bien compris l'histoire du / as prenom non plus

    Merci de m'éclairer de vos lumières et de prendre le temps de me répondre
    Ex développeur Php / J2EE.
    Actuellement reconverti à SharePoint 2013

    Mon blog SP 2013

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 102
    Points : 120
    Points
    120
    Par défaut
    bah si si t'as la main sur ta base genre avec phpmyadmin, clique sur SQL et patate une des requetes, elles sont pretes pour l'emploi.

    Pour etre plus clair, UNION sert à cumuler les resultats de 2 ou plusieurs requetes a conditions qu'elles aient la même gueule. (memes noms/structures de champs dans la clause SELECT)

    par exemple, je cumule dans le même jeu d'enregistrement

    un select sur les messages des user + un select sur lesmessages des groupes

    mon premier ex , le plus simple renvoie tous les message pour user suivi de tous le smessages pour groupe, en comblant le champ 'prenom' avec "/" pour le cas groupe.


    Mon 2 eme exemple ajoute un champs qui stipule quel type dedestinataire
    en terme de retour ca afficherait quelque chose comme çà:

    type_dest | nom | prenom | message
    Utilisateur | DUPOND | paul | son_messageblablasdfsd
    Utilisateur | Janvion | Gerard| son_messageblabla_a_gerard
    Utilisateur |Zimako | Jacques | son_messageblablahdskjfhsd
    Groupe |groupe1| / | son_messageblabla_au_groupe1
    Groupe |groupe2 |/ |son_messageblablahdskjfhsd_groupe2

    Mon 2 eme exemple englobe ces resultat dans une pseudo table formée par une sousrequete (la meme que l'exemple 2) de maniere a pouvoir manipuler la table (ORDER BY, GROUP BY etc.), chose impossible avec dans chacune des requetes UNION.

    je classe par nom les resultat au dessus (order by nom) et ca donne :

    type_dest | nom | prenom | message
    Utilisateur | DUPOND | paul | son_messageblablasdfsd
    Groupe |groupe1| / | son_messageblabla_au_groupe1
    Groupe |groupe2 |/ |son_messageblablahdskjfhsd_groupe2
    Utilisateur | Janvion | Gerard| son_messageblabla_a_gerard


    remarque : d'apres ce que tu me dit dans ton dernier post, tu peux rempacer '/' par NULL (sans les quotes) pour obtenir des champs vides.
    Utilisateur |Zimako | Jacques | son_messageblablahdskjfhsd
    il n'y a pas de sotte existence

Discussions similaires

  1. Conditions sur tables jointes
    Par KpTn dans le forum Hibernate
    Réponses: 1
    Dernier message: 12/10/2007, 11h17
  2. [SQL] Problème condition sur 1 table
    Par Dwain dans le forum Langage SQL
    Réponses: 3
    Dernier message: 27/02/2007, 20h51
  3. [Oracle] Pb conditions sur tables multiples
    Par guitou12 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 04/08/2006, 16h48
  4. [Access] requete sql avec condition sur date
    Par qeja dans le forum Langage SQL
    Réponses: 4
    Dernier message: 26/03/2006, 00h54
  5. Condition sur un multiple de ....!
    Par Orakle dans le forum Access
    Réponses: 2
    Dernier message: 08/03/2006, 16h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo