查询及物动词翻译

时间:2018-12-16 14:35:20

标签: sql sqlite

我在构建应该为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->德国。

2 个答案:

答案 0 :(得分:0)

我建议将您的餐桌设计更改为以下几行:

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'

Demo

这里的想法是,您希望其中一个表维护每个逻辑上不同的单词到某个常见ID或引用的映射。然后,您只需要输入单词和语言以及所需的输出语言即可进行映射。

注意:为简单起见,我只显示一种表,其中包含几种语言中的单个单词,但逻辑仍应适用于多种单词和语言。您当前的表格可能未进行规范化,但优化可能是与您当前的问题分开的另一项任务。

答案 1 :(得分:0)

这是一个复杂的图形行走问题。这个想法是建立一个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';

Here是db <>小提琴。

大概,您需要最短的路径。为此,您可以使用此查询(在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);