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

时间:2016-09-22 21:21:29

标签: mysql sql

制备

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

if let email = emp.getEmail() {
    let workEmail = CNLabeledValue(label: CNLabelWork, value: email as NSString)
    contact.emailAddresses = [workEmail]
}

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

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 | +----+-----------+ 中的ref_subtab1maintable id subtable1ref_subtab2列最终引用id {1}}。我想选择subtable2中以上述方式间接引用的所有行。

我试过了

subtable2

但这会返回6个结果,一个用于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; 中的每个匹配:

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 |
+----+-----------+

使用MySQL语句可以有效地完成吗?

1 个答案:

答案 0 :(得分:0)

如上所述,请使用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;