mysql - 选择在另一个表中间接引用的行

标签 mysql sql

准备工作

考虑此脚本来创建 MySQL 虚拟数据库:

CREATE SCHEMA `zzz_dummy` ;
CREATE TABLE `zzz_dummy`.`subtable2` (
  `id` INT NOT NULL UNIQUE,
  `col1` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));
CREATE TABLE `zzz_dummy`.`subtable1` (
  `id` INT NOT NULL UNIQUE,
  `ref_subtab2` INT NULL,
  PRIMARY KEY (`id`));
CREATE TABLE `zzz_dummy`.`maintable` (
  `id` INT NOT NULL UNIQUE,
  `ref_subtab1` INT NULL,
  PRIMARY KEY (`id`));

ALTER TABLE `zzz_dummy`.`maintable` 
ADD INDEX `fk_subtab1_idx` (`ref_subtab1` ASC);
ALTER TABLE `zzz_dummy`.`maintable` 
ADD CONSTRAINT `fk_subtab1`
  FOREIGN KEY (`ref_subtab1`)
  REFERENCES `zzz_dummy`.`subtable1` (`id`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION;


ALTER TABLE `zzz_dummy`.`subtable1` 
ADD INDEX `fk_subtab2_idx` (`ref_subtab2` ASC);
ALTER TABLE `zzz_dummy`.`subtable1` 
ADD CONSTRAINT `fk_subtab2`
  FOREIGN KEY (`ref_subtab2`)
  REFERENCES `zzz_dummy`.`subtable2` (`id`)
  ON DELETE NO ACTION
  ON UPDATE NO ACTION;

INSERT INTO zzz_dummy.subtable2 VALUES
  (1,'ref_val_1'),
  (2,'ref_val_2'),
  (3,'no_ref');

INSERT INTO zzz_dummy.subtable1 VALUES
  (1,'1'),
  (2,'2'),
  (3,'3');

INSERT INTO zzz_dummy.maintable VALUES
  (1,'1'),
  (2,'2'),
  (3,'1'),
  (4,'1'),
  (5,'2'),
  (6,'1');

这将生成以下表格和条目:

maintable:
+----+-------------+
| id | ref_subtab1 |
+----+-------------+
|  1 |           1 |
|  3 |           1 |
|  4 |           1 |
|  6 |           1 |
|  2 |           2 |
|  5 |           2 |
+----+-------------+

subtable1:
+----+-------------+
| id | ref_subtab2 |
+----+-------------+
|  1 |           1 |
|  2 |           2 |
|  3 |           3 |
+----+-------------+

subtable2:
+----+-----------+
| id | col1      |
+----+-----------+
|  1 | ref_val_1 |
|  2 | ref_val_2 |
|  3 | no_ref    |
+----+-----------+

问题

可以看到,maintable中的列ref_subtab1引用了subtable1中的id,该列ref_subtab2最终引用了subtable2中的id。我想选择 subtable2 中以上述方式间接引用的所有行。

我已经尝试过

SELECT subtable2.* FROM zzz_dummy.subtable2
  INNER JOIN zzz_dummy.maintable
  INNER JOIN zzz_dummy.subtable1
  WHERE zzz_dummy.maintable.ref_subtab1=zzz_dummy.subtable1.id
    AND zzz_dummy.subtable1.ref_subtab2=zzz_dummy.subtable2.id;

但这会返回 6 个结果,maintable 中的每个匹配项都有一个结果:

+----+-----------+
| id | col1      |
+----+-----------+
|  1 | ref_val_1 |
|  1 | ref_val_1 |
|  1 | ref_val_1 |
|  1 | ref_val_1 |
|  2 | ref_val_2 |
|  2 | ref_val_2 |
+----+-----------+

我不需要多余的值,我希望它返回:

+----+-----------+
| id | col1      |
+----+-----------+
|  1 | ref_val_1 |
|  2 | ref_val_2 |
+----+-----------+

可以使用 MySQL 语句高效地完成此操作吗?

最佳答案

正如已经评论的那样,使用 distinct 来获取唯一的结果组合,并将这些条件从 WHERE 子句移动到 JOIN ON 条件,例如

SELECT distinct subtable2.* 
FROM zzz_dummy.subtable2
  INNER JOIN zzz_dummy.subtable1
  ON zzz_dummy.subtable1.ref_subtab2 = zzz_dummy.subtable2.id
  INNER JOIN zzz_dummy.maintable 
 ON zzz_dummy.maintable.ref_subtab1 = zzz_dummy.subtable1.id;

关于mysql - 选择在另一个表中间接引用的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39649066/

相关文章:

php - Drupal 6.x View 如何查询与单个内容相关的多个分类术语?

mysql - Code-igniter MySql 中的 Json 数组问题

Mysql 错误在第 1153 行 : Unknown command '\'

java - Eclipse SDK 3.2.0 JAVA 到 Oracle 存储过程

mysql - 如何修复插入后触发计数时mysql代码中的错误

sql - 动态生成小数点

php - 出现错误数据库未选择

php - CDbConnection无法打开数据库连接: unable to open database file

sql - H2数据库中的Oracle MERGE语句

php - 根据是否已选中复选框,使用OR语句创建SQL查询