Получить строки по транзитивности в MySQL
Предположим, у меня есть следующая таблица:
Images
|id | similarTo|
|---|----------|
|1 | 2 |
|2 | 3 |
|--------------|
Где SimilarTo - это внешний ключ к идентификатору. То, что я хочу, это запрос, который может получить транзитивное закрытие идентификатора до 2 уровней в обоих направлениях. Другими словами, мы имеем: A -> B ---> C, а также C -> B -> A
И поэтому в этом случае я хотел бы вернуть:
Given 1: 2,3
Given 2: 1,3
Given 3: 1,2
По сути, я храню функцию (изображение A) аналогично (изображение B) в таблице. Эта функция работает в обоих направлениях, поэтому, если A похож на B, то B похож на A. Теперь мне нужен запрос, который может найти все изображения, похожие на данное изображение, до двух уровней / шагов... (то есть, если учитывая A -> B -> C -> D, теперь, если я хочу найти все изображения, похожие на A, он вернул бы B,C)
1 ответ
Может быть запрос, как показано ниже:
SELECT
id,
similarTo
From images
UNION ALL
SELECT
t1.id,
t2.similarTo
FROM images t1
INNER JOIN images t2 ON t1.similarTo = t2.id AND t1.id < t2.id
Второй запрос фактически порождает transitive
связь. И первый получает все определенные отношения в вашей таблице.
Выход:
Вы получите вывод, как показано ниже:
| id | similarTo |
|----|-----------|
| 1 | 2 |
| 2 | 3 |
| 1 | 3 |
РЕДАКТИРОВАТЬ:
Для конкретных id
сказать id=2
:
SELECT
id,
similarTo
From images
WHERE id=2 or similarTo=2
UNION ALL
SELECT
t1.id,
t2.similarTo
FROM images t1
INNER JOIN images t2 ON t1.similarTo=2 AND t2.id =2 AND t1.id < t2.id