ПОДГОТОВКАВыберите строки, которые косвенно ссылаются в другой таблице
Рассмотрим этот скрипт для создания 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 |
+----+-----------+
ПРОБЛЕМА
Как вы можете видеть, столбец ref_subtab1
в maintable
ссылок id
в subtable1
, что колонка 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'. вы получаете избыточные строки из-за отношений «один-много». –
@vkp Является ли мой подход менее эффективным или есть лучший способ сделать это? – nautical