代码之家  ›  专栏  ›  技术社区  ›  Mario

寻找这些矛盾的最有效方法?

  •  0
  • Mario  · 技术社区  · 6 年前

    这个项目由一个表组成,我们称之为 Table 为了简化由C程序处理的三列:

    • ID 是唯一的身份证在这里并不重要
    • Source 包括输入文本。
    • Translation 包括内容的修改/翻译版本 .

    Example Table

    如您所见,该表遵循某种模式,其目标是根据这些规则查找不一致:

    • 所有id都是唯一的,并且没有可用的关联来连接彼此之间的相关条目。
    • 来源 包含大多数不遵循此模式的条目(上面省略)。
    • 如果有记录的话 来源 设置为 ABC 另一张唱片 来源 设置为 Map: ABC Map: 之后是A 来源 翻译 Karte: 然后 翻译 翻译 列应该遵循与 来源 .
    • 在上面的示例表中,查询的结果应该告诉您 ID_34567 ID_45678 不匹配,因为 翻译 因为后者是 Karte: Project B Karte: Projekt B (由 翻译 属于 身份证号码34567 ).
    • 查询(或查询)应该在SQLite中实现,托管在C代码中(因此它不必100%只在SQLite中实现)。
    • 可用的SQLite命令扩展为用于正则表达式匹配(PCRE2)的自定义函数,例如 rxmatch(rx, text) text 匹配正则表达式或 0 以防不匹配。此列表可以根据需要展开或修改。

    地图: 条目:

    select ID, rxmatch('(?<=Map: ).*', Source) as ms, rxmatch('(?<=: ).*', Translation) as mt from `Table` where ms != 0 and mt != 0;
    

    对每个结果行运行第二个查询,并检查是否存在不一致以返回它们(它从 a / b 但为了可读性我省略了这些)。使用的参数是上面返回的三列(id、匹配的源部分、匹配的目标部分)。

    select ... as translation from `Table` as a inner join `Table` as b on a.ID = ? and b.Source = ? and not b.Translation = ?;
    

    虽然这非常好用,但它不是最快的查询,我想知道是否有一种更优雅的方法来简化它并同时加速它。

    1 回复  |  直到 6 年前
        1
  •  2
  •   CL.    6 年前
    SELECT ...
    FROM MyTable AS A
    JOIN MyTable AS B ON 'Map: '   || A.Source      =  B.Source
                     AND 'Karte: ' || A.Translation <> B.Translation;
    

    这需要一个索引 Source 要有效率(或者更好的是 covering index 来源 Translation ,如果您有磁盘空间)。