วิธีสร้างการรวมทางขวาหลายรายการในคำสั่งเดียวสำหรับตารางลูกที่แตกต่างกัน
ในภาพต่อไปนี้คุณจะเห็น 3 ตาราง: A, B, C A: เป็นตารางที่เก็บคีย์ต่างประเทศจาก B และ C


ถ้าฉันทำการรวมอย่างถูกต้องระหว่าง A และ B กับคีย์ต่างประเทศนั้นมันใช้งานได้หมายความว่าฉันได้รับข้อมูลจากคอลัมน์ fooB เหมือนกันระหว่าง A และ C กับ fooC
แต่ถ้าฉันใส่การรวมขวาทั้งสองภายใต้คำสั่งเดียวกันมันจะล้มเหลวด้วย null
+-------------+---------------+
| fooB | fooC |
+-------------+---------------+
| NULL | abc |
| NULL | xyz |
* สิ่งนี้แตกต่างเล็กน้อยจากรูปภาพที่มีคำสั่งที่โพสต์ด้านล่างเนื่องจากสิ่งนี้มาจากการปรับใช้จริงโดยตรงอย่างไรก็ตาม cmds ด้านล่างยังคงแสดงว่าทั้งสองคอลัมน์ไม่ปรากฏขึ้น
ฉันได้ลองผสมการรวมทางซ้ายการรวมทางขวาการรวมภายนอกทั้งหมดด้วยผลลัพธ์เดียวกัน ฉันได้ Googled เกี่ยวกับเรื่องนี้แล้ว แต่วิธีการกำหนดคำถามของฉันนั้นแย่มากและความนิยมที่ฉันได้รับกลับเป็นการรวมที่ถูกต้องแบบดั้งเดิมเพียงแค่ตารางเดียว
ฉันจะทำให้สิ่งนี้ทำงานในคำสั่งเดียวได้อย่างไร CMDS ด้านล่าง:

คำสั่งเดียวกับด้านบน แต่เป็นข้อความเนื่องจากความคิดเห็นกำลังขอข้อความมากกว่ารูปภาพ:
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 |
+------+
- นี่คือสคริปต์ทั้งหมด -
-- 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;
ผลลัพธ์ที่ต้องการในคำสั่งเดียว:
+-------------+---------------+
| fooB | fooC |
+-------------+---------------+
| b1 | c1 |
| b2 | c2 |
คำตอบ
สิ่งที่คุณต้องการคือ INNER JOIN
หากต้องการยกเว้นแถวคุณสามารถใช้คำสั่ง WHERE ปกติหรือทำในส่วนคำสั่ง ON
แผนผัง (MySQL v8.0)
แบบสอบถาม # 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 |
ดูใน DB Fiddle