Запрос на переходный перевод слова - PullRequest
0 голосов
/ 16 декабря 2018

У меня проблемы с построением того, что, как мне кажется, должно быть запросом CTE, который бы возвращал перевод слова.

У меня есть две таблицы - СЛОВА:

ID | WORD | LANG
1   'Cat'   'ENG'
2   'Kot'   'POL'
3   'Katze' 'GER'

и СОЕДИНЕНИЯ:

ID | WORD_A | WORD_B
1       1         2
2       1         3

Поскольку переводы ENG-> POL и ENG-> GER уже существуют, я хотел бы получить перевод POL-> GER.

Так что для любого данного слова я должен проверитьэто связанные переводы, если целевого языка нет, я должен проверить связанные переводы этих связанных переводов и т. д., до того момента, когда будет найден либо перевод, либо ничего не возвращено;

Я понятия не имею, куданачать, это не было бы проблемой, если бы требовалось постоянное количество переходов, но это также может потребовать переход, такой как POL-> ITA -> ...-> ENG-> GER.

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Это сложная задача обхода графа.Идея состоит в том, чтобы установить отношение connections2, которое имеет слова и языки в обоих направлениях, а затем использовать это для перемещения по графику.

Чтобы получить все немецкие переводы для польских слов, вы можете использовать:

with words AS (
      select 1 as id, 'Cat' as word, 'ENG' as lang union all
      select 2, 'Kot', 'POL' union all
      select 3, 'Katze', 'GER'
     ),
     connections as (
      select 1 as id, 1 as word_a, 2 as word_b union all
      select 2 as id, 1 as word_a, 3 as word_b
     ),
     connections2 as (
      select c.word_a as id_a, c.word_b as id_b, wa.lang as lang_a, wb.lang as lang_b
      from connections c join
           words wa
           on c.word_a = wa.id join
           words wb
           on c.word_b = wb.id
      union  -- remove duplicates
      select c.word_b, c.word_a, wb.lang as lang_a, wa.lang as lang_b
      from connections c join
           words wa
           on c.word_a = wa.id join
           words wb
           on c.word_b = wb.id
     ),
     cte as (
      select id as pol_word, id as other_word, 'POL' as other_lang, 1 as lev, ',POL,' as langs
      from words
      where lang = 'POL'
      union all
      select cte.pol_word, c2.id_b, c2.lang_b, lev + 1, langs || c2.lang_b || ','
      from cte join
           connections2 c2
           on cte.other_lang = c2.lang_a
      where langs not like '%,' || c2.lang_b || ',%' or c2.lang_b = 'GER'
     ) 
select *
from cte
where cte.other_lang = 'GER';

Здесь - это дБ <> скрипка.

Предположительно, вы хотите кратчайший путь.Для этого вы должны использовать этот запрос (после CTE):

select *
from cte
where cte.other_lang = 'GER' and
      cte.lev = (select min(cte2.lev) from cte cte2 where ct2.pol_word = cte.pol_word);
0 голосов
/ 16 декабря 2018

Я рекомендую изменить дизайн таблицы на что-то вроде этого:

ID | WORD_ID | WORD    | LANG
1  | 1       | 'Cat'   | 'ENG'
2  | 1       | 'Kot'   | 'POL'
3  | 1       | 'Katze' | 'GER'

Теперь предположим, что вы хотите перейти с польского на немецкий, и вы начинаете с польского слова для кошки, Kot.Затем вы можете использовать следующий запрос:

SELECT t2.WORD
FROM yourTable t1
INNER JOIN yourTable t2
    ON t1.WORD_ID = t1.WORD_ID AND t2.LANG = 'GER'
WHERE
    t1.WORD = 'Kot' AND t1.LANG = 'POL'

Демо

Идея заключается в том, что вы хотите, чтобы одна из ваших таблиц поддерживаласьотображение каждого логически отличного слова в некоторый общий идентификатор или ссылку.Тогда вам нужно только входящее слово и язык и желаемый выходной язык, чтобы можно было выполнять сопоставление.

Примечание. Для простоты я показываю только таблицу с одним словом на нескольких языках., но логика должна работать с несколькими словами и языками.Ваша текущая таблица не может быть нормализована, но ее оптимизация может быть другой задачей, отдельной от вашего непосредственного вопроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...