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 :

LEFT JOIN qui marche ? pas normal !


Sujet :

Requêtes MySQL

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 36
    Points : 38
    Points
    38
    Par défaut LEFT JOIN qui marche ? pas normal !
    Bonjour !

    j'utilise un LEFT JOIN dans ma requete du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT table1.id , table2.id FROM table1 LEFT JOIN table2 ON table1.jointure = table2.id WHERE ...
    tout se passe bien ! (cool !)

    MAIS

    dans le champ jointure il y a des enregistrements de type : "45-44-48" (id séparé par '-') et MySQL fait une jointure sur l'id 45 pour aller le chercher dans table2 en vrai ca m'arrange bien mais ... avant de continuer a coder ainsi si c une erreur autant recommencer d'aplomb de suite ! quand pensez vous ?

    Mysql gère t'il cette particularité en natif ou est ce jouer avec le feu en exploitant une sorte de tolérance ?

    l'objectif final de l'opération :
    recuperer les infos des autres id (dans l'exemple 44 et 48) mais dans la plupart des cas il n'y a qu'1 id dans ce champ et si il y en a plusieurs je fait une autre requete avec php (je regroupe toutes les id concernées puis clause IN (id-id-...)
    on m'a parler de creer une table de jointure qui ferait le lien entre la table1 et la table2 car impossibilité de demander a mysql de faire la requete avec un champ de ce type !)

    Merci pour vos lumières

  2. #2
    Membre expérimenté
    Avatar de Adjanakis
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    739
    Détails du profil
    Informations personnelles :
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2004
    Messages : 739
    Points : 1 351
    Points
    1 351
    Par défaut
    Bonjour,

    Bien sûr que c'est possible de faire avec la structure actuelle. MySQL fournit plein de méthode sympathique dans le genre de REPLACE et FIND_IN_SET par exemple. Le problème c'est que ce type de fonctionnement est assez lourd et pas performant pour un sous.

    Effectivement, comme l'on te la conseiller, la solution la plus propre serait de créer une table supplémentaire traduisant l'association de ces 2 entités.
    Pensez au tag

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 36
    Points : 38
    Points
    38
    Par défaut
    Merci ! pour ta réponse

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 36
    Points : 38
    Points
    38
    Par défaut utilisation de plusieurs table de jointure !!
    alors j'essayes d'appliquer la methode de la table de jointure en lieu et place de mon champ concatener!

    et je galere beaucoup pour ecrire la requete qui va avec alors je vous presente mes tables de test :
    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
     
    CREATE TABLE `act` (
      `id_act` int(11) NOT NULL auto_increment,
      `nom_act` text collate utf8_unicode_ci NOT NULL,
      PRIMARY KEY  (`id_act`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10000 ;
     
    -- --------------------------------------------------------
     
    -- 
    -- Structure de la table `event`
    -- 
     
    CREATE TABLE `event` (
      `id_event` int(11) NOT NULL auto_increment,
      `nom_event` text collate utf8_unicode_ci NOT NULL,
      PRIMARY KEY  (`id_event`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10001 ;
     
    -- --------------------------------------------------------
     
    -- 
    -- Structure de la table `event_act`
    -- 
     
    CREATE TABLE `event_act` (
      `id_event_ea` int(11) unsigned NOT NULL,
      `id_act_ea` int(11) unsigned NOT NULL,
      `priority_ea` tinyint(4) NOT NULL,
      KEY `_id_event_` (`id_event_ea`,`id_act_ea`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    -- --------------------------------------------------------
     
    -- 
    -- Structure de la table `event_lieux`
    -- 
     
    CREATE TABLE `event_lieux` (
      `id_event_el` int(11) unsigned NOT NULL,
      `id_lieux_el` int(11) unsigned NOT NULL,
      `priority_el` tinyint(4) NOT NULL,
      KEY `id_lieux_el` (`id_lieux_el`,`priority_el`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    -- --------------------------------------------------------
     
    -- 
    -- Structure de la table `event_org`
    -- 
     
    CREATE TABLE `event_org` (
      `id_event_eo` int(10) unsigned NOT NULL,
      `id_org_eo` int(10) unsigned NOT NULL,
      `priority_eo` tinyint(4) NOT NULL,
      KEY `id_event_eo` (`id_event_eo`,`id_org_eo`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
     
    -- --------------------------------------------------------
     
    -- 
    -- Structure de la table `lieux`
    -- 
     
    CREATE TABLE `lieux` (
      `id_lieux` int(11) NOT NULL auto_increment,
      `nom_lieux` text collate utf8_unicode_ci NOT NULL,
      `region_lieux` int(11) NOT NULL,
      PRIMARY KEY  (`id_lieux`),
      KEY `region_lieux` (`region_lieux`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10000 ;
     
    -- --------------------------------------------------------
     
    -- 
    -- Structure de la table `org`
    -- 
     
    CREATE TABLE `org` (
      `id_org` int(11) NOT NULL auto_increment,
      `nom_org` text collate utf8_unicode_ci NOT NULL,
      PRIMARY KEY  (`id_org`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10000 ;
     
    -- --------------------------------------------------------
     
    -- 
    -- Structure de la table `ville`
    -- 
     
    CREATE TABLE `ville` (
      `id_ville` mediumint(8) unsigned NOT NULL default '0',
      `nom_ville` tinytext collate utf8_unicode_ci NOT NULL,
      `cp_ville` tinytext collate utf8_unicode_ci NOT NULL,
      `dep_ville` tinyint(4) NOT NULL default '0',
      PRIMARY KEY  (`id_ville`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    le principe :
    - 1 'event' auquel sont rattaché : 1 ou plusieurs 'org' (via table de liason event_org), 'act' (via table de liason event_act), 'lieux' (via table de liason event_lieux et qui est lui meme lié a la table 'ville' en jointure naturelle sur region_lieux=id_ville!)

    et j'ai fait plusieurs test mais les resultats ne me conviennent pas du tout j'ai creer pour voir sur l'event 1 > 10 liason act, 10 liasons org, 10 liaison lieux

    et je fait la requete suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT event.*,lieux.*,org.*,ville.*
    FROM event 
    LEFT JOIN event_act ON id_event_ea=id_event
    LEFT JOIN act ON id_act_ea=id_act
    LEFT JOIN event_lieux ON id_event_el=id_event
    LEFT JOIN lieux ON id_lieux_el=id_lieux
    LEFT JOIN event_org ON id_event_eo=id_event
    LEFT JOIN org ON id_org_eo=id_org
    LEFT JOIN ville ON region_lieux=id_ville
    WHERE id_event=1
    mysql me retourne 737 enregistrements !!??

    alors je dois me planter quelques part ?

    mon but recuperer les infos de l'event et les infos de chaque org,act,lieux lié dans un tableau

    si il y a un spécialiste qui passe par la et qu'il peut me conseiller sur la syntaxe des jointures ou de la requete en elle meme

    j'ai pensé a un moment a faire la requete en deux fois dans le sens ou je peux compter le nombre d'entrées de chaque liasons pour creer des alias qui me permettent de reecrir la requete en fonction du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT event.*,
    lieux.nom_lieux as nom_lieux1,
    lieux.nom_lieux as nom_lieux2,
    lieux.nom_lieux as nom_lieux3,...
    org.nom_org as nom_org1,
    org.nom_org as nom_org2,...
    enfin bon je cherche !! sur le net et sur la doc ... et j'attend peut etre une piste de votre part

    MERCI



    PS requete imbriqué pas d'accord non plus avec :
    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
     
     SELECT event. * , lieux. * , org. * , act. * , ville. *
    FROM event, act, org, lieux
    LEFT JOIN ville ON region_lieux = id_ville
    WHERE id_act
    IN (
     
    SELECT id_act_ea
    FROM event_act
    WHERE id_event_ea =1
    )
    AND id_lieux
    IN (
     
    SELECT id_lieux_el
    FROM event_lieux
    WHERE id_event_el =1
    )
    AND id_org
    IN (
     
    SELECT id_org_eo
    FROM event_org
    WHERE id_event_eo =1
    )
    AND id_event =1
    LIMIT 0 , 30
    =729 enregistrements il croise toutes les possibilitées !

  5. #5
    Membre expérimenté
    Avatar de Adjanakis
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    739
    Détails du profil
    Informations personnelles :
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2004
    Messages : 739
    Points : 1 351
    Points
    1 351
    Par défaut
    Ce n'est pas à MySQL de devoir lister tous les noms d'un évènement sur une seule ligne. Quand bien même ce serait le cas, il faudrait utiliser une fonction telle que GROUP_CONCAT pour regrouper tous les noms dans un seul champ en les séparant par une virgule par exemple.
    Pensez au tag

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 36
    Points : 38
    Points
    38
    Par défaut
    justement la question est :

    pour obtenir les meilleures performance (rapidité du serveur sql) quelle type de requete et quelle organisataion des tables choisir ?

    je ne connais pas les fonctions de ce type (et notamment l'amélioration par rapport a la methode 2 requetes avec php ca je maitrise ![je recupere une liste complete puis je range tout les id qu'il me faut pour envoyer une deuxieme requete correspondant a l'ensemble de la liste]) et je ne sais comment m'organiser (de facon correcte et efficaces) y arriver ca je me débrouille mais faire comme il faut ca c autre chose.

    peut etre pourrai tu me renseigner ?

    Merci

  7. #7
    Membre expérimenté
    Avatar de Adjanakis
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    739
    Détails du profil
    Informations personnelles :
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Avril 2004
    Messages : 739
    Points : 1 351
    Points
    1 351
    Par défaut
    Pour bien faire les choses, il faudrait commencer par ne pas avoir de champs contenant une liste d'identifiant. (cf '45-44-48') Une nouvelle table devrait être créee pour incarner l'association.

    Pour obtenir une liste de nom, l'utilisation de GROUP_CONCAT peut être bonne.
    Pensez au tag

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 36
    Points : 38
    Points
    38
    Par défaut
    excelent !!
    cette fonction est tout pile ce qui me fallait !
    vraiment merci !!

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 06/05/2015, 16h53
  2. Left outer join, ne marche pas
    Par lido dans le forum Forms
    Réponses: 5
    Dernier message: 04/06/2008, 12h05
  3. Réponses: 12
    Dernier message: 12/03/2008, 16h56
  4. [LG]Split qui marche pas
    Par macluvitch dans le forum Langage
    Réponses: 3
    Dernier message: 30/11/2003, 18h19
  5. Sysdate qui marche pas ??
    Par StouffR dans le forum Langage SQL
    Réponses: 4
    Dernier message: 28/08/2002, 13h23

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