Comment faire plusieurs jointures à droite en une seule commande pour différentes tables enfants ?
Sur l'image suivante vous voyez 3 tables : A, B , C. A : est la table qui contient les clés étrangères de B et C
Si je fais une jointure droite entre A et B sur cette clé étrangère, cela fonctionne, ce qui signifie que j'obtiens les données de la colonne fooB. Idem entre A et C avec fooC.
Mais si je mets les deux jointures droites sous la même commande, cela échoue avec null
+-------------+---------------+
| fooB | fooC |
+-------------+---------------+
| NULL | abc |
| NULL | xyz |
* Ceci est légèrement différent de l'image avec les commandes affichées ci-dessous, car cela vient directement du déploiement réel, cependant les cmds ci-dessous montrent toujours que les deux colonnes ne s'affichent pas.
J'ai essayé de mélanger les jointures gauches, les jointures droites, les jointures externes avec le même résultat. J'ai cherché sur Google à ce sujet, mais la façon dont ma question est formulée est maladroite et les résultats que je reçois renvoient les jointures droites traditionnelles pour une seule table.
Comment puis-je faire fonctionner cela en une seule commande? CMDS ci-dessous :
Mêmes commandes que ci-dessus mais dans le texte, car les commentaires demandent du texte plutôt que des images :
MariaDB [joinPOC]> select fooB from tableA right join tableB on tableB_idtableB=tableB.idtableB;
+------+
| fooB |
+------+
| b1 |
| b2 |
| b3 |
+------+
3 rows in set (0.001 sec)
MariaDB [joinPOC]> select fooC from tableA right join tableC on tableC_idtableC=tableC.idtableC;
+------+
| fooC |
+------+
| c1 |
| c2 |
| c3 |
+------+
3 rows in set (0.001 sec)
MariaDB [joinPOC]> select fooB from tableA right join tableB on tableB_idtableB=tableB.idtableB right join tableC on tableC_idtableC=tableC.idtableC;
+------+
| fooB |
+------+
| b1 |
| b2 |
| b3 |
+------+
--VOICI LE SCRIPT EN ENTIER--
-- MySQL Workbench Forward Engineering
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
-- -----------------------------------------------------
-- Schema joinPOC
-- -----------------------------------------------------
DROP SCHEMA IF EXISTS `joinPOC` ;
-- -----------------------------------------------------
-- Schema joinPOC
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `joinPOC` ;
USE `joinPOC` ;
-- -----------------------------------------------------
-- Table `joinPOC`.`tableB`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `joinPOC`.`tableB` (
`idtableB` INT NOT NULL,
`fooB` VARCHAR(10) NOT NULL,
PRIMARY KEY (`idtableB`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `joinPOC`.`tableC`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `joinPOC`.`tableC` (
`idtableC` INT NOT NULL,
`fooC` VARCHAR(10) NOT NULL,
PRIMARY KEY (`idtableC`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `joinPOC`.`tableA`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `joinPOC`.`tableA` (
`idtableA` INT NOT NULL,
`fooA` VARCHAR(10) NOT NULL,
`tableB_idtableB` INT NOT NULL,
`tableC_idtableC` INT NOT NULL,
PRIMARY KEY (`idtableA`),
INDEX `fk_tableA_tableB_idx` (`tableB_idtableB` ASC),
INDEX `fk_tableA_tableC1_idx` (`tableC_idtableC` ASC),
CONSTRAINT `fk_tableA_tableB`
FOREIGN KEY (`tableB_idtableB`)
REFERENCES `joinPOC`.`tableB` (`idtableB`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tableA_tableC1`
FOREIGN KEY (`tableC_idtableC`)
REFERENCES `joinPOC`.`tableC` (`idtableC`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
-- -----------------------------------------------------
-- Data for table `joinPOC`.`tableB`
-- -----------------------------------------------------
START TRANSACTION;
USE `joinPOC`;
INSERT INTO `joinPOC`.`tableB` (`idtableB`, `fooB`) VALUES (1, 'b1');
INSERT INTO `joinPOC`.`tableB` (`idtableB`, `fooB`) VALUES (2, 'b2');
INSERT INTO `joinPOC`.`tableB` (`idtableB`, `fooB`) VALUES (3, 'b3');
COMMIT;
-- -----------------------------------------------------
-- Data for table `joinPOC`.`tableC`
-- -----------------------------------------------------
START TRANSACTION;
USE `joinPOC`;
INSERT INTO `joinPOC`.`tableC` (`idtableC`, `fooC`) VALUES (1, 'c1');
INSERT INTO `joinPOC`.`tableC` (`idtableC`, `fooC`) VALUES (2, 'c2');
INSERT INTO `joinPOC`.`tableC` (`idtableC`, `fooC`) VALUES (3, 'c3');
COMMIT;
-- -----------------------------------------------------
-- Data for table `joinPOC`.`tableA`
-- -----------------------------------------------------
START TRANSACTION;
USE `joinPOC`;
INSERT INTO `joinPOC`.`tableA` (`idtableA`, `fooA`, `tableB_idtableB`, `tableC_idtableC`) VALUES (1, 'a1', 1, 1);
INSERT INTO `joinPOC`.`tableA` (`idtableA`, `fooA`, `tableB_idtableB`, `tableC_idtableC`) VALUES (2, 'a2', 2, 2);
INSERT INTO `joinPOC`.`tableA` (`idtableA`, `fooA`, `tableB_idtableB`, `tableC_idtableC`) VALUES (3, 'a3', 3, 3);
COMMIT;
Sortie souhaitée en une seule commande :
+-------------+---------------+
| fooB | fooC |
+-------------+---------------+
| b1 | c1 |
| b2 | c2 |
Réponses
Ce que vous voulez, c'est un INNER JOIN.
Pour exclure des lignes, vous pouvez utiliser la clause WHERE normale ou le faire dans la clause ON
Schéma (MySQL v8.0)
Requête #1
SELECT
b.fooB, c.fooC
FROM
tableA a
INNER JOIN
tableB b ON a.tableB_idtableB = b.idtableB
INNER JOIN
tableC c ON a.tableC_idtableC = c.idtableC;
| fooB | fooC |
| ---- | ---- |
| b1 | c1 |
| b2 | c2 |
| b3 | c3 |
Voir sur DB Fiddle