Làm cách nào để tạo nhiều phép nối phải trong một lệnh duy nhất cho các bảng con khác nhau?
Trên hình ảnh sau, bạn thấy 3 bảng: A, B, C. A: Là bảng chứa khóa ngoại từ B và C
Nếu tôi thực hiện phép nối phải giữa A và B trên khóa ngoại đó, nó hoạt động, nghĩa là tôi lấy dữ liệu từ cột fooB. Tương tự giữa A và C với fooC.
Nhưng nếu tôi đặt cả hai phép nối bên phải dưới cùng một lệnh, nó không thành công với null
+-------------+---------------+
| fooB | fooC |
+-------------+---------------+
| NULL | abc |
| NULL | xyz |
* Điều này hơi khác so với hình ảnh với các lệnh được đăng bên dưới, vì điều này đến trực tiếp từ triển khai thực, tuy nhiên các cmds bên dưới vẫn cho thấy rằng cả hai cột không hiển thị.
Tôi đã thử kết hợp các phép nối bên trái, phép nối phải, phép nối bên ngoài, tất cả đều có cùng kết quả. Tôi đã tìm kiếm trên Google về điều này, nhưng cách câu hỏi của tôi được xây dựng rất khó hiểu và các lần truy cập tôi nhận được trả về các phép nối phải truyền thống chỉ cho một bảng.
Làm cách nào để làm cho điều này hoạt động trong một lệnh? CMDS bên dưới:
Các lệnh tương tự như trên nhưng ở dạng văn bản, vì nhận xét yêu cầu văn bản thay vì hình ảnh:
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 |
+------+
- CÓ TOÀN BỘ KHOẢNG CÁCH--
-- 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;
Đầu ra mong muốn trong một lệnh duy nhất:
+-------------+---------------+
| fooB | fooC |
+-------------+---------------+
| b1 | c1 |
| b2 | c2 |
Trả lời
Những gì bạn muốn là THAM GIA BÊN TRONG.
Để loại trừ các hàng, bạn có thể sử dụng mệnh đề WHERE thông thường hoặc thực hiện trong mệnh đề BẬT
Lược đồ (MySQL v8.0)
Truy vấn số 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 |
Xem trên DB Fiddle