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

Requêtes MySQL Discussion :

Jointures conditionnelles MYSQL pour traductions


Sujet :

Requêtes MySQL

  1. #1
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Par défaut Jointures conditionnelles MYSQL pour traductions
    Bonjour et tout d'abord merci du temps que vous prendrez pour me lire,

    je suis embêté par une jointure

    TABLE1 -> T1 = articles
    TABLE1_TRAD -> colonne TRAD_LG peut avoir des valeurs entre 1 et 4 par exemple ( 1 = FR, 2 = EN, 3 = IT, 4 = ES...)

    je voudrais que lorsque je sélectionne les éléments de la table TABLE1_TRAD, si il n'y a pas de traduction en FR, il utilise la ligne de la table TABLE1_TRAD avec valeur TRAD_LG = 2 qui sera la traduction obligatoire et par défaut...

    Pour le moment j'ai fait ça, mais je ne pense pas que ce soit optimisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
    SELECT T1F.TRAD_TITRE as titre, T1E.TRAD_TITRE as titre_d FROM TABLE1 T1 
              LEFT JOIN TABLE1_TRAD T1F ON (T1F.TRAD_LG = $valeur)
              LEFT JOIN TABLE1_TRAD T1E ON (T1E.TRAD_LG = 2)
    Et après je fait une condition PHP si titre existe alors on n'utilise pas titre_d...
    est-il possible de faire une jointure conditionnelle qui prends par défaut TRAD_LANG = 2 si il ne trouve pas la langue proposé correspondant à $valeur ?

    Merci encore pour l'aiguillage qui me manque

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 138
    Par défaut
    C'est là qu'intervient la fonction COALESCE !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT  COALESCE(T1F.TRAD_TITRE, T1E.TRAD_TITRE) AS titre_d
    FROM    TABLE1 T1
        INNER JOIN
            TABLE1_TRAD T1E
            ON  T1E.TRAD_LG = 2
        LEFT JOIN
            TABLE1_TRAD T1F
            ON  T1F.TRAD_LG = $valeur
    S'il y a toujours une traduction dans la langue 2, autant utiliser un INNER JOIN.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Par défaut
    Bonjour AL1_24 et merci pour ta réponse,

    Ok, donc ça améliore un petit peu le résultat, mais je suis content de savoir qu'il n'y a pas vraiment d'autre solution pour la partie FROM

    J'ai une autre question qui en découle :

    Prenons les différentes tables TABLE1 (article sur les voitures par exemple), TABLE2 (motos), TABLE3 (camions) etc etc...

    Une table permet de répertorié les nouveaux ajouts avec un petit message rajoutable :

    TABLE_NEWS :
    TN_M_ID => identifiant de l'une des tables ci-dessus
    TN_CAT => 1 = TABLE1 / 2 = TABLE2 etc...
    TN_MESS => message optionel

    Donc pour appeler la liste des ajouts d'un membre avec le descriptif de l'élément ajouté :

    est-il plus optimisé de faire comme ceci :

    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
     
     
    SELECT  COALESCE(T1F.TRAD_TITRE, T1E.TRAD_TITRE) AS titre_d1 ...
    FROM    
        TABLE_NEWS TN 
     
        LEFT JOIN TABLE1 T1 ON  (TN.TN_CAT = 1 && TN.TN_M_ID = T1.T1_ID)
        INNER JOIN TABLE1_TRAD T1E ON  (T1E.TRAD_LG = 2 && T1E.T1E_M_ID = T1.T1_ID)
        LEFT JOIN   TABLE1_TRAD T1F  ON  (T1F.TRAD_LG = $valeur && T1F.T1F_M_ID = T1.T1_ID)
     
        LEFT JOIN TABLE2 T2 ON  (TN.TN_CAT = 2 && TN.TN_M_ID = T2.T2_ID)
        INNER JOIN TABLE2_TRAD T2E ON  (T2E.TRAD_LG = 2 && T2E.T2E_M_ID = T2.T2_ID)
        LEFT JOIN   TABLE2_TRAD T2F  ON  (T2F.TRAD_LG = $valeur && T2F.T2F_M_ID = T2.T2_ID)
     
        LEFT JOIN TABLE3 T3 ON  (TN.TN_CAT = 3 && TN.TN_M_ID = T3.T3_ID)
        INNER JOIN TABLE3_TRAD T3E ON  (T3E.TRAD_LG = 2 && T3E.T3E_M_ID = T3.T3_ID)
        LEFT JOIN   TABLE3_TRAD T3F  ON  (T3F.TRAD_LG = $valeur && T3F.T3F_M_ID = T3.T3_ID)
     
    ...
    etc... dans le cas ici présent, il aurait besoin de chercher jusqu'à TABLE 8...

    ( chaque table est équipé de clé étrangères biensûr pour les optimiser mais malgré tout j'aimerai savoir l'avis des experts pour ce genre de requête assez grosses )

    ou bien de faire un appel de la table TN_MESS TN puis faire une boucle PHP et ensuite faire un appel de l'élément de la catégorie comme TABLE 1 si la TN_CAT = 1 ?

    Et merci encore pour votre aide précieuse !!

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 138
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 138
    Par défaut
    Si les tables table1..8 ont une structure équivalente, tu peux passer par une union et, pourquoi pas, créer une vue pour y placer la sous-requête.
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    SELECT  trd.titre
    FROM    TABLE_NEWS TN
        INNER JOIN
            (   SELECT  1                                         AS  cat_tn
                    ,   T1F.TRAD_LG                               AS  trad_lg
                    ,   T1.T1_ID                                  AS  tbl_id
                    ,   COALESCE(T1F.TRAD_TITRE, T1E.TRAD_TITRE)  AS  titre
                FROM    TABLE1 T1 
                    INNER JOIN 
                        TABLE1_TRAD T1E 
                        ON  T1E.TRAD_LG   = 2 
                        AND T1E.T1E_M_ID  = T1.T1_ID
                    LEFT JOIN   
                        TABLE1_TRAD T1F  
                        ON  T1F.T1F_M_ID  = T1.T1_ID
            UNION ALL
                SELECT  2                                         AS  cat_tn
                    ,   T2F.TRAD_LG                               AS  trad_lg
                    ,   T2.T2_ID                                  AS  tbl_id
                    ,   COALESCE(T2F.TRAD_TITRE, T2E.TRAD_TITRE)  AS  titre
                FROM    TABLE2 T2 
                    INNER JOIN 
                        TABLE2_TRAD T2E 
                        ON  T2E.TRAD_LG   = 2 
                        AND T2E.T2E_M_ID  = T2.T2_ID
                    LEFT JOIN   
                        TABLE2_TRAD T2F  
                        ON  T2F.T2F_M_ID  = T2.T2_ID
            ...
            )   trd
            ON  TN.TN_M_ID  = trd.tbl_id
            AND TN.TN_CAT   = trd.cat_tn 
            AND (   trd.cat_lg  = $valeur
                OR  trd.cat_lg  IS NULL
                )
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 212
    Par défaut
    Salut seifscalp.

    Citation Envoyé par seifscalp
    je suis embêté par une jointure
    Pourquoi faire une jointure supplémentaire pour accéder à la valeur par défaut ?

    Citation Envoyé par seifscalp
    je voudrais que lorsque je sélectionne les éléments de la table TABLE1_TRAD, si il n'y a pas de traduction en FR, il utilise la ligne de la table TABLE1_TRAD avec valeur TRAD_LG = 2 qui sera la traduction obligatoire et par défaut...
    Pourquoi ne pas mettre votre valeur par défaut en dernière position dans votre table ? Par exemple, "99 = EN".

    Voici ce que je propose selon votre exemple :
    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    --------------
    SET AUTOCOMMIT = 0
    --------------
     
    --------------
    START TRANSACTION
    --------------
     
    --------------
    DROP DATABASE IF EXISTS `base`
    --------------
     
    --------------
    CREATE DATABASE `base`
            DEFAULT CHARACTER SET `latin1`
            DEFAULT COLLATE       `latin1_general_ci`
    --------------
     
    --------------
    DROP TABLE IF EXISTS `article`
    --------------
     
    --------------
    CREATE TABLE `article`
    ( `id`    integer unsigned NOT NULL auto_increment primary key,
      `lang`  tinyint unsigned NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `article` (`lang`) VALUES (1), (3), (5), (7)
    --------------
     
    --------------
    select * from article
    --------------
     
    +----+------+
    | id | lang |
    +----+------+
    |  1 |    1 |
    |  2 |    3 |
    |  3 |    5 |
    |  4 |    7 |
    +----+------+
    --------------
    DROP TABLE IF EXISTS `trad`
    --------------
     
    --------------
    CREATE TABLE `trad`
    ( `clef`  integer unsigned NOT NULL primary key,
      `lib`   varchar(255)     NOT NULL
    ) ENGINE=InnoDB
      DEFAULT CHARSET=`latin1` COLLATE=`latin1_general_ci`
      ROW_FORMAT=COMPRESSED
    --------------
     
    --------------
    INSERT INTO `trad` (`clef`, `lib`) VALUES
    (1,  'Libellé en français'),
    (2,  'Wording in English'),
    (3,  'Denominati in italiano'),
    (4,  'denominados en español'),
    (99, 'Wording in English')
    --------------
     
    --------------
    select * from trad
    --------------
     
    +------+------------------------+
    | clef | lib                    |
    +------+------------------------+
    |    1 | Libellé en français    |
    |    2 | Wording in English     |
    |    3 | Denominati in italiano |
    |    4 | denominados en español |
    |   99 | Wording in English     |
    +------+------------------------+
    --------------
    select  *
          from  article as a
     
    inner join  trad    as t
            on  t.clef in (a.lang, 99)
     
      group by  a.lang
    --------------
     
    +----+------+------+------------------------+
    | id | lang | clef | lib                    |
    +----+------+------+------------------------+
    |  1 |    1 |    1 | Libellé en français    |
    |  2 |    3 |    3 | Denominati in italiano |
    |  3 |    5 |   99 | Wording in English     |
    |  4 |    7 |   99 | Wording in English     |
    +----+------+------+------------------------+
    --------------
    COMMIT
    --------------
     
    --------------
    SET AUTOCOMMIT = 1
    --------------
     
    Appuyez sur une touche pour continuer...
    Et du coup, au lieu de faire deux jointures, vous n'en avez plus qu'une seule !

    Attention, je n'ai pas dit que la solution proposé par Al1_24 est mauvaise.
    Mais quand on peut faire plus simple, autant le faire !

    Citation Envoyé par seifscalp
    Prenons les différentes tables TABLE1 (article sur les voitures par exemple), TABLE2 (motos), TABLE3 (camions) etc etc...
    Pourquoi créer autant de tables différentes, si elles ont toutes la même structure ?
    Autant en faire une seule et ajouter une colonne supplémentaire pour les différenciers.
    Par exemple, "type_vehicule", avec 1 = voiture, 2 = moto, 3 = camion, ...
    D'ailleurs, en utilisant "UNION" comme le propose Al1_24, c'est comme si vous aviez une seule table.

    Avez-vous une raison particulière pour découper cela en huit tables ?

    Citation Envoyé par seifscalp
    est-il plus optimisé de faire comme ceci :
    Non !

    Je pense que vous devez revoir votre modélisation car vous avez trop de tables qui sont similaires.
    1 table pour vos véhicule (1 = voiture, 2 = moto, 3 = camion, ...)
    1 table pour vos traductions.

    @+

  6. #6
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Par défaut
    Tout d'abord merci beaucoup à vous deux,

    j'ai posté sur ce post https://www.developpez.net/forums/d1...l/#post9279674

    ma question sur l'héritage, car je ne savais pas si j'avais le droit d'écrire plusieurs questions au même endroit vu que j'avais déjà eu une réponse, sorry !

    J'ai lu attentivement vos deux réponses et elles m'ont éclairés sur beaucoup de choses, mais je crois que je dois revoir un peu la modélisation de certains éléments dans mes tables comme vous me le conseillez ! Sur l'autre poste j'ai détaillé les questions qui me manquent encore pour finir de comprendre comment bien faire mon héritage de table

    Et merci encore à vous deux !!

  7. #7
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    7 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 7 212
    Par défaut
    Salut seifscalp.

    Je n'ai jamais bien compris, quand un projet est plus qu'entamé, que l'on se pose des questions sur la faisabilité !
    La modélisation ainsi que les notions de performances sont complètement indépendants du développement d'un projet.
    Créer une base de données, c'est une étude complètement à part du développement d'un projet et qui vent en amont !
    C'est dans cette étude que l'on se pose justement toutes les questions que vous vous posez.
    Par exemple, le modèle entité-relation qui permet déjà de définir une ébauche de votre futur base de données.
    Le dictionnaire des données, les règles de gestions ...
    A l'issu de cela, on passe au modèle physique, et sur cette première version, on fait toutes les requêtes qui vont servir au projet.
    C'est là que l'on va dégrader la base afin d'améliorer les performances.
    Chaque nouvelle version va permettre de visualiser ce qui va et ce qui ne va pas et ainsi de tendre vers ce qui semble être le mieux.

    C'est surtout à un travail de synthèse qui se fait bien avant le développement.
    Quand débute le développement, en principe, on ne doit pas se poser des questions de faisabilités ni de performances car ce n'est pas le travail du développeur.
    Mais il arrive parfois des oublis où il est nécessaire de revenir en arrière afin de résoudre un problème que l'on n'a pas rencontré au préalable.

    Ce travail de modélisation se termine par un dossier dont le développeur aura sous le coude toutes les réponses qu'il se pose.
    Ce travail est réalisé par un administrateur qui connait la modélisation des bases de données, la fonctionnelle et le développement.
    C'est un travail de synthèse entre divers métiers qui font défaut à beaucoup de gens qui abordent ce genre de projet.

    @+

  8. #8
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2015
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2015
    Messages : 10
    Par défaut
    Merci pour cette réponse,

    j'ai en effet pas une équipe, mais je suis seul pour le développement du projet, sur lequel je boss depuis 2 ans à peu près, je ne suis pas du métier d'origine mais j'ai beaucoup appris en travaillant, je sais très bien que j'aurai pas mal de choses à revoir le jour du passage aux versions suivantes et à ce moment là, si il y a version suivante c'est que le système fonctionnera relativement bien, je me ferai aider par des spécialistes qui pourront y améliorer les éléments problématiques et que je pourrai rémunérer.

    Pour le moment, je n'ai pas les moyens financiers d'engager des spécialistes dans chaque domaine alors je code un système qui n'est pas parfait mais qui marchera quand même, puis il sera amélioré quand je pourrais bosser avec des gens qui auront des compétences plus expérimentées

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] MySql: jointure de tables pour maillage interne
    Par amdawb dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 23/11/2014, 23h39
  2. Réponses: 3
    Dernier message: 28/05/2008, 18h00
  3. Réponses: 2
    Dernier message: 04/11/2006, 01h33
  4. Encore une jointure sous Oracle pour la route
    Par ebaynaud dans le forum Langage SQL
    Réponses: 15
    Dernier message: 04/11/2004, 12h40
  5. Requete MySql pour Mambo Open source
    Par azman0101 dans le forum Requêtes
    Réponses: 2
    Dernier message: 22/06/2004, 10h34

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