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

Langage SQL Discussion :

Difficulté sur 2 requêtes avec jointures


Sujet :

Langage SQL

  1. #1
    Membre actif
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Points : 271
    Points
    271
    Par défaut Difficulté sur 2 requêtes avec jointures
    Bonjour à toutes et à tous,

    je n'arrive pas à concevoir mes requêtes.
    Peut être à cause de la modélisation de la base... je sais pas.
    Règles:
    -Une personne peut travailler dans plusieurs établissements
    -Un service est propre à un établissement

    Voici la base 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
     
    -- T_ETABLISSEMENT
     
    CREATE TABLE `t_etablissement` (
      `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
      `nom` VARCHAR(100) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    INSERT INTO `t_etablissement` (`id`, `nom`) VALUES
    (1, "E1"),
    (2, "E2"),
    (3, "E3"),
    (4, "E4"),
    (5, "E5"),
    (6, "E6");
     
    -- T_SERVICE
     
    CREATE TABLE `t_service` (
      `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
      `nom` VARCHAR(100) NOT NULL,
      `id_etablissement` SMALLINT(5) UNSIGNED NOT NULL,
      PRIMARY KEY (`id`),
      FOREIGN KEY (`id_etablissement`) REFERENCES `t_etablissement` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    INSERT INTO `t_service` (`id`, `nom`, `id_etablissement`) VALUES
    (1, "S1 pour E1", 1),
    (2, "S2 pour E4", 4),
    (3, "S3 pour E4", 4);
     
    -- T_PERSONNE
     
    CREATE TABLE `t_personne` (
      `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT,
      `civilite` ENUM("","Mr","Mme","Mlle") NOT NULL,
      `nom` VARCHAR(50) NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    INSERT INTO `t_personne` (`id`, `civilite`, `nom`) VALUES 
    (1, "Mr", "P1"),
    (2, "Mlle", "P2"),
    (3, "Mr", "P3"),
    (4, "Mr", "P4"),
    (5, "Mr", "P5"),
    (6, "Mr", "P6"),
    (7, "Mme", "P7"),
    (8, "Mme", "P8"),
    (9, "Mr", "P9"),
    (10, "Mr", "P10");
     
    -- T_APPARTENANCE
     
    CREATE TABLE `t_appartenance` (
      `id_personne` SMALLINT(5) UNSIGNED NOT NULL,
      `id_etablissement` SMALLINT(5) UNSIGNED NOT NULL,
      `id_service` SMALLINT(5) UNSIGNED,
      `statut` VARCHAR(50) DEFAULT "",
      `tel` VARCHAR(10) DEFAULT "",
      PRIMARY KEY  (`id_personne`, `id_etablissement`),
      FOREIGN KEY (`id_personne`) REFERENCES `t_personne` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
      FOREIGN KEY (`id_etablissement`) REFERENCES `t_etablissement` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION,
      FOREIGN KEY (`id_service`) REFERENCES `t_service` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    INSERT INTO `t_appartenance` (`id_personne`, `id_etablissement`, `id_service`, `statut`, `tel`) VALUES 
    (1, 1, 1, "E1-S1 -> Directeur Général", "0101010101"),
    (2, 1, 1, "E1-S1 -> Assistante de direction", "0202020202"),
    (3, 1, NULL, "E1 -> Informaticien", "0303030303"),
    (3, 2, NULL, "E2 -> Informaticien", "0303030303"),
    (6, 4, 2, "E4-S2 -> Directeur", "0606060606"),
    (7, 4, 3, "E4-S3 -> Responsable", "0707070707"),
    (8, 4, NULL, "E4 -> Secrétaire", "0808080808"),
    (9, 4, 3, "E4-S3 -> Stagiaire", "0909090909"),
    (10, 6, NULL, "E6 -> Stagiaire", "1010101010");
    J'aimerais par exemple obtenir :
    1/ la liste des personnes du service S3 avec toutes les infos dispo.
    requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT 
    	E.nom AS e_nom, S.nom AS s_nom, 
    	P.id AS p_id, P.nom AS p_nom, 
    	A.statut AS a_statut, A.tel AS a_tel
    FROM 
    	t_etablissement E
    		INNER JOIN t_service S ON S.id_etablissement = E.id
    		LEFT JOIN t_appartenance A ON A.id_etablissement = E.id
    		LEFT JOIN t_personne P ON P.id = A.id_personne
    WHERE 
    	S.id = 3;
    ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    E4  	S3 pour E4  	6  	P6  	E4-S2 -> Directeur  	0606060606
    E4 	S3 pour E4 	7 	P7 	E4-S3 -> Responsable 	0707070707
    E4 	S3 pour E4 	8 	P8 	E4 -> Secrétaire 	0808080808
    E4 	S3 pour E4 	9 	P9 	E4-S3 -> Stagiaire 	0909090909
    au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    E4 	S3 pour E4 	7 	P7 	E4-S3 -> Responsable 	0707070707
    E4 	S3 pour E4 	9 	P9 	E4-S3 -> Stagiaire 	0909090909
    et de la même manière :
    2/ la liste des personnes travaillant à E1
    requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT 
    	E.nom AS e_nom, S.nom AS s_nom, 
    	P.id AS p_id, P.nom AS p_nom, 
    	A.statut AS a_statut, A.tel AS a_tel
    FROM 
    	t_etablissement E
    		INNER JOIN t_service S ON S.id_etablissement = E.id
    		LEFT JOIN t_appartenance A ON A.id_etablissement = E.id
    		LEFT JOIN t_personne P ON P.id = A.id_personne
    WHERE 
    	E.id = 1;
    ce qui donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    E1  	S1 pour E1  	1  	P1  	E1-S1 -> Directeur Général  	0101010101
    E1 	S1 pour E1 	2 	P2 	E1-S1 -> Assistante de direction 	0202020202
    E1 	S1 pour E1 	3 	P3 	E1 -> Informaticien 	0303030303
    au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    E1  	S1 pour E1  	1  	P1  	E1-S1 -> Directeur Général  	0101010101
    E1 	S1 pour E1 	2 	P2 	E1-S1 -> Assistante de direction 	0202020202
    E1 	NULL 		3 	P3 	E1 -> Informaticien 	0303030303
    Quelqu'un pourrait-il m'aider SVP ?
    Merci d'avance


  2. #2
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Liste des personnes du service S3 avec toutes les infos dispo.


    Il faudrait déjà établir une jointure entre les tables t_appartenance et t_service :


    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT 
    	E.nom AS e_nom, S.nom AS s_nom, 
    	P.id AS p_id, P.nom AS p_nom, 
    	A.statut AS a_statut, A.tel AS a_tel
    FROM 
    	t_etablissement E
    		INNER JOIN t_service S ON S.id_etablissement = E.id
    		LEFT JOIN t_appartenance A ON A.id_etablissement = E.id  
                      AND A.id_service = S.id
    		LEFT JOIN t_personne P ON P.id = A.id_personne
    WHERE 
    	S.id = 3;

    Ensuite, puisque le service est obligatoirement attaché à un établissement et qu'une appartenance est obligatoirement attachée à une personne et à un établissement, vous pouvez remplacer chaque outer join par une jointure naturelle :


    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT 
    	E.nom AS e_nom, S.nom AS s_nom, 
    	P.id AS p_id, P.nom AS p_nom, 
    	A.statut AS a_statut, A.tel AS a_tel
    FROM 
    	t_etablissement E
    		INNER JOIN t_service S ON S.id_etablissement = E.id
    		INNER JOIN t_appartenance A ON A.id_etablissement = E.id 
                      AND A.id_service = S.id
    		INNER JOIN t_personne P ON P.id = A.id_personne
    WHERE 
    	S.id = 3;

    ___________________

    Liste des personnes travaillant à E1

    On conserve les jointures naturelles entre les tables t_etablissement, t_appartenance et t_personne, En revanche, la jointure avec t_service doit être faite en relation avec t_appartenance, puisque c’est dans cette table que l’attribut id service peut être marqué NULL (et du fait de NULL, cette fois-ci il faut utiliser un outer join, il a été inventé pour ça).

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT 
    	E.nom AS e_nom, S.nom AS s_nom, 
    	P.id AS p_id, P.nom AS p_nom, 
    	A.statut AS a_statut, A.tel AS a_tel
    FROM 
    	t_etablissement E
    		INNER JOIN t_appartenance A ON A.id_etablissement = E.id
    		INNER JOIN t_personne P ON P.id = A.id_personne
    		LEFT JOIN t_service S ON S.id_etablissement = A.id_service
    WHERE 
    	E.id = 1;
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #3
    Membre actif
    Inscrit en
    Octobre 2005
    Messages
    908
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 908
    Points : 271
    Points
    271
    Par défaut
    Un GRAND MERCI à toi fsmrel !

    ça marche nickel...

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

Discussions similaires

  1. Aide sur une requête avec jointure et LIMIT 1
    Par mister3957 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 28/06/2013, 20h17
  2. Réponses: 16
    Dernier message: 20/01/2011, 12h45
  3. Besoin aide sur une requête avec jointure
    Par PoichOU dans le forum Requêtes
    Réponses: 3
    Dernier message: 31/08/2010, 18h32
  4. Aide sur une requête avec jointure..
    Par WeDgEMasTeR dans le forum Requêtes
    Réponses: 7
    Dernier message: 10/11/2009, 18h09
  5. Lenteur sur une requête avec jointure
    Par mister3957 dans le forum SQL
    Réponses: 16
    Dernier message: 13/08/2008, 13h10

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