【问题标题】:Oracle - Search for Word within a WordOracle - 在一个单词中搜索单词
【发布时间】:2018-03-17 15:58:30
【问题描述】:

我希望有一个大脑可以帮助一个迷失的灵魂;

我有两列; COL_ACOL_B,两列的每条记录都只包含一个单词(单词的长度可以变化)。

我要做的是搜索COL_A 并识别与COL_B 的部分(单词)匹配,例如COL_A = 'MSOFT'COL_B = 'MICROSOFT',因此这将被归类为匹配。

同样,如果 COL_A = 'RANGE'COL_B = 'ORANGE' 这也将被归类为匹配项。

但是,如果 COL_A = 'ORGAN'COL_B = 'ORANGE' 这不会被归类为匹配项。

我愿意接受建议(纯 SQL、函数等)。

一如既往,我们将不胜感激。

非常感谢!

【问题讨论】:

  • 仍然不清楚你所说的匹配是什么意思。因此,如果 col_A = 'RANGE' 和 col_B = 'ORANGE' 匹配;如果 col_A = 'ORANGE' 和 col_B = 'RANGE' 仍然匹配吗?哪个是另一个的子词有关系吗?然后:这两个词之间的区别是否必须是一个连续的子字符串(如在所有示例中一样),或者 'ALMA' 是否匹配 'KALIMERA'?
  • 嗨,Mathguy,为歧义道歉; COL_A 将始终包含少于或相同数量的字符作为 COL_B。关于字符串;是的,它将是一个连续的子字符串(因此“ALMA”和“KALIMERA”不会被视为匹配。非常感谢。
  • 好的,所以匹配意味着第一行是初始子字符串,最终子字符串(意味着在末尾锚定),还是初始子字符串后跟最终子字符串的连接?任何其他情况都意味着“差异”不连续。请确认。然后:有趣的问题!不确定它在现实生活中的适用性如何,但这是一个很好的挑战(非常重要,因为有多种匹配方法)。
  • 确实,很有趣 - 在过去的几个小时里,我一直在脑痛。从理论上讲,它可能是两者的串联......也就是说,我相信采用最终的子字符串将是一个很好的起点。
  • 所以,为了清楚起见——“误报”(在文本匹配中)有时被称为“母亲在 chemotherapy”问题(原因我强调)。但是,根据我们的规则,这不是匹配,因为差异是由两个不连贯的字符串组成的,开头是“che”,结尾是“apy”。只是确保...

标签: sql string oracle search plsql


【解决方案1】:

类似这样的东西..这将适用于您的示例数据

SELECT *
  FROM yourtable
WHERE INSTR(col_a,col_b,1)>0
   OR INSTR(col_b,col_a,1)>0
   or INSTR(substr(col_a,2,length(col_a)), col_b,1)>0
   or INSTR(substr(col_b,2,length(col_b)), col_a,1)>0

【讨论】:

    【解决方案2】:

    这是解决此问题的简单方法。它不漂亮,而且可能效率不高(但问题本身可能没有非常有效的解决方案,就其性质而言)。不过,它应该易于阅读、理解和维护。

    我假设 col_a 中的 NULL 被视为“空字符串”,因此无论 col_b 中的内容如何,​​它都匹配 col_b。如果您想将其视为实际的 NULL,则可以在 MATCH 列中返回 'N' 或者更好的是 NULL。

    with
         inputs ( col_a, col_b ) as (
           select 'MSOFT', 'MICROSOFT' from dual union all
           select 'RANGE', 'ORANGE'    from dual union all
           select 'BLUES', 'BLUES'     from dual union all
           select 'ORGAN', 'ORANGE'    from dual union all
           select 'ALMA' , 'KALIMERA'  from dual union all
           select null   , 'OCTOPUS'   from dual union all
           select 'ALPHA', 'ALPHABET'  from dual
         )
    -- End of simulated inputs (for testing only, not part of the solution).
    -- SQL query begins BELOW THIS LINE. Use your actual table and column names.
    select col_a, col_b,
           case when col_a is null then 'Y'
                when exists ( select level from dual
                              where col_a = substr( col_b, 1, level - 1 ) || 
                                              substr( col_b, -(length(col_a) - level + 1),
                                                               length(col_a) - level + 1 )
                              connect by level <= length(col_a) + 1
                            )
                                   then 'Y'
                                   else 'N' end as match
    from  inputs;
    
    COL_A COL_B     M
    ----- --------- -
    MSOFT MICROSOFT Y
    RANGE ORANGE    Y
    BLUES BLUES     Y
    ORGAN ORANGE    N
    ALMA  KALIMERA  N
          OCTOPUS   Y
    ALPHA ALPHABET  Y
    

    【讨论】:

    • 谢谢,Mathguy - 这看起来可以完成这项工作。惊人的!你是明星!
    【解决方案3】:

    一个简单的like 条件就可以解决问题:

    SELECT *
    FROM   mytable
    WHERE  col_a LIKE '%' || col_b || '%'
    

    【讨论】:

    • 感谢 Mureinik 的及时回复。我确实尝试过使用上述方法,但不幸的是它似乎不能满足我的要求。我认为(我可能是错的)但根据我的测试,这仅适用于整个单词而不是部分单词(例如,如果 COL_A = 'SOFT' 和 COL_B = 'MICROSOFT' 它会匹配,但如果 COL_A = '微软')。而我需要“MSOFT”才能算作匹配。
    • 另请参阅我对 OP 的评论 - 我是否遗漏了什么,或者您只是猜测此解决方案的全部要求?
    猜你喜欢
    • 2013-09-17
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多