В одном направлении: ID_1 - это имя, ID_2 - это синоним:
select
sn.NAME
from
NAMES_TABLE n
inner join SYNONYMS_TABLE s on s.ID_1 = n.ID
inner join NAMES_TABLE sn on sn.ID2 = s.ID_2
where
n.NAME = :NAME
Два направления: либо ID_1, либо ID_2 могут содержать имя, а другое - его синоним.
select
sn1.NAME
from
NAMES_TABLE n1
inner join SYNONYMS_TABLE s1 on s1.ID_1 = n1.ID
inner join NAMES_TABLE sn1 on sn1.ID = s1.ID_2
where
n1.NAME = :NAME
union
select
sn2.NAME
from
NAMES_TABLE n2
inner join SYNONYMS_TABLE s2 on s2.ID_2 = n2.ID
inner join NAMES_TABLE sn2 on sn2.ID = s2.ID_1
where
n2.NAME = :NAME
Обратите внимание, что ID_2 и ID_1 меняются во второй части второго запроса.
Какой из них вам нужен, зависит от данных.Если вы хотите, чтобы «дорожка» была синонимом «дороги», а не наоборот, вам следует использовать первый метод.Но в этом случае вы должны помнить, что синонимы в обоих направлениях должны быть добавлены дважды, поэтому вы получите:
NAMES_TABLE SYNONYMS_TABLE
------------ --------------
ID | NAME ID_1 | ID_2
---+-------- ------+-------
1 | Road 1 | 3
2 | Lane 3 | 1
3 | Street 2 | 1
Теперь Road и Street являются синонимами друг друга, но Lane является синонимом.для дороги, дорога не для переулка.Если вы не хотите такого поведения, вам лучше использовать второе, хотя вы можете рискнуть ввести двойные записи, поменяв местами ID_1 и ID_2.Вы должны быть в состоянии предотвратить это, проверив, что ID_2 всегда выше, чем ID_1, никогда не бывает одинаковым или ниже.