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 :

auto jointure MySql


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de moukit233
    Développeur informatique
    Inscrit en
    Mai 2009
    Messages
    240
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2009
    Messages : 240
    Par défaut auto jointure MySql
    Salut,
    j'ai une table Mysql :
    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
     
    CREATE TABLE IF NOT EXISTS `maTable` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `type` enum('type1','type2','type3','type4') collate utf8_bin NOT NULL,
      `idLangue` tinyint(3) unsigned NOT NULL default '1',
      `idReference` int(10) unsigned default NULL,
      PRIMARY KEY  (`id`),
      KEY `idLangue` (`idLangue`),
      KEY `idReference` (`idReference`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
     
    --
    -- Contraintes pour la table `maTable`
    --
    ALTER TABLE `maTable`
      ADD CONSTRAINT `maTable_ibfk_5` FOREIGN KEY (`idReference`) 
           REFERENCES `maTable` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
    je veux recupere toutes les enregistrements dont le type = "type1" et la langue = 2 (premier condition),
    et toutes les enregistrements dont la langue != 2 + idReference est null et que leurs ids != idReference des enregistrements retourné par la 1er condition

    j'ai essayé avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT * 
    FROM `maTable`
    WHERE (idLangue = 2 and type = "type1")
    OR
    (idLangue != 2 
     and idReference is NULL 
     and type = "type1"
     and id not in (select idReference from `maTable` where (idLangue = 2 and type = "type1"))
    )
    mais je prefere d'utilise la jointure (autojointure)
    merci de m'aider

  2. #2
    Membre émérite Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Par défaut
    Bonjour,

    Vous pouvez utiliser l'opérateur UNION:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id, type FROM maTable WHERE type = 'type1' AND idLangue = 2
    UNION
    SELECT id, type FROM maTable WHERE idLangue != 2 AND idReference IS NULL
    je veux recupere toutes les enregistrements dont le type = "type1" et la langue = 2 (premier condition),
    et toutes les enregistrements dont la langue != 2 + idReference est null et que leurs ids != idReference des enregistrements retourné par la 1er condition
    Vous recherchez les lignes pour lesquels:
    type = 'type1' ET langue = 2
    et
    idReference = NULL ET langue <> 2

    Le "et" entre les deux ensembles de prédicat se traduit par un OU dans une clause WHERE.
    Forcément, vous n'aurait jamais de "doublons", à cause des critères sur langue.
    L'ensemble respectant la première condition ne verra jamais une de ses lignes retournées dans l'ensemble correspondant à la seconde condition.

    Un simple WHERE devrait donc suffire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT id, type
    FROM maTable
    WHERE
      (type ='type1' AND idLangue = 2)
        OR
      (idReference IS NULL AND idLangue <> 2)

  3. #3
    Membre éclairé Avatar de moukit233
    Développeur informatique
    Inscrit en
    Mai 2009
    Messages
    240
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2009
    Messages : 240
    Par défaut
    Re,
    merci de votre réponse
    Citation Envoyé par Oishiiii Voir le message
    Bonjour,

    Vous pouvez utiliser l'opérateur UNION:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT id, type FROM maTable WHERE type = 'type1' AND idLangue = 2
    UNION
    SELECT id, type FROM maTable WHERE idLangue != 2 AND idReference IS NULL
    pour votre information les valeur idReference = les valeurs id ( c'est à dire idReference clef étrangère de la id)
    pour votre requête tu as oublié une condition :
    - les enregistrements retournés par la première condition ne doivent pas avoir dans la colonne une id (numero) d'un des enregistrement retournés par la seconde condition.

    comme on a deux requêtes dans une seule requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * 
    FROM `maTable`
    WHERE (idLangue = 2 AND type = "type1")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT * 
    FROM `maTable`
    WHERE (idLangue != 2 
     AND idReference IS NULL 
     AND type = "type1"
     AND id NOT IN (SELECT idReference FROM `maTable` WHERE (idLangue = 2 AND type = "type1"))
    )

  4. #4
    Membre émérite Avatar de Oishiiii
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2009
    Messages
    508
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2009
    Messages : 508
    Par défaut
    Mea Culpa, effectivement j'ai lu trop vite.

    Vous serez toujours obligé passer par une sous-requête, opérateurs IN ou EXISTS. Une auto-jointure n'apportera rien, il faudrait alors placer la sous-requête dans la clause de jointure ?

  5. #5
    Membre éclairé Avatar de moukit233
    Développeur informatique
    Inscrit en
    Mai 2009
    Messages
    240
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2009
    Messages : 240
    Par défaut
    Citation Envoyé par Oishiiii Voir le message
    il faudrait alors placer la sous-requête dans la clause de jointure ?
    merci de me dire comment ?

  6. #6
    Membre éclairé Avatar de moukit233
    Développeur informatique
    Inscrit en
    Mai 2009
    Messages
    240
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2009
    Messages : 240
    Par défaut
    en fait
    j'ai essayé les jointures mais ça n'a pas l'air de marcher ??

    par contre j'ai une autre question :
    - qu'elle est la plus performante parmi les deux requêtes suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT * 
    FROM `maTable`
    WHERE (idLangue = 2 AND type = "type1")
    OR
    (idLangue != 2 
     AND idReference IS NULL 
     AND type = "type1"
     AND id NOT IN (SELECT idReference FROM `maTable` WHERE (idLangue = 2 AND type = "type1"))
    )
    ou bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    SELECT * 
    FROM `maTable`
    WHERE (idLangue = 2 AND type = "type1")
    UNION 
    SELECT * 
    FROM `maTable`
    WHERE (idLangue != 2 
     AND idReference IS NULL 
     AND type = "type1"
     AND id NOT EXISTS (SELECT idReference FROM `maTable` WHERE (idLangue = 2 AND type = "type1"))
    )

Discussions similaires

  1. Auto jointure complexe
    Par ricobye dans le forum Langage SQL
    Réponses: 11
    Dernier message: 19/01/2006, 16h02
  2. Trier la hierarchie d'une auto-jointure
    Par Oberown dans le forum Langage SQL
    Réponses: 8
    Dernier message: 17/10/2005, 16h18
  3. [Jointure] MySQL - Exemple
    Par Stef.web dans le forum Langage SQL
    Réponses: 2
    Dernier message: 22/10/2004, 20h41
  4. resultat d'une auto jointure
    Par slc dans le forum Requêtes
    Réponses: 6
    Dernier message: 30/09/2004, 13h54
  5. Auto jointure speciale
    Par kv000 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 14/04/2004, 13h02

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