在字符串中搜索特定字符 - Oracle

时间:2014-01-22 17:58:43

标签: sql oracle

我遇到过以下场景,

我有一个列名Broker_name,其中的几个值是'tpt Broker','Mark iii', 'Davidtpt'

这些值的最终输出应该是'TPT Broker', 'Mark III','Davidtpt'基本上我需要CAPS在字符串Say TPT 中的几个预定义值,它带有尾随空格,罗马字母等。

所以我创建了一个具有

的查找表
Column1 Column2
tpt      TPT
iii      III

请告诉我如何检查字符串中是否存在特定字符,然后对表进行查找。基于那个?

2 个答案:

答案 0 :(得分:1)

最后,我设法在一个MODEL子句的帮助下处理它:

SELECT id, broker_name FROM (
  SELECT id, broker_name, rn, val, replacement
  FROM brokers CROSS JOIN (SELECT rownum AS rn, val, replacement FROM lookup)
  MODEL
    PARTITION BY (id)
    DIMENSION BY (rn)
    MEASURES (val, replacement, broker_name)
    RULES (
      broker_name[ANY] = regexp_replace(nvl(broker_name[CV()-1], broker_name[CV()]),
                                        '(^|.*\W)' || val[CV()] || '(\W.*|$)',
                                        '\1' || replacement[CV()] || '\2')
    )
)
WHERE rn = (SELECT count(*) FROM lookup)
ORDER BY id, broker_name;

基本上它执行以下操作:

  1. 为查询表中的项目编号
  2. 在经纪人和查询之间执行交叉连接
  3. 对于每个代理,它遍历查找值并进行替换(有点奇怪的正则表达式确保只替换整个单词)
  4. 最后,它只占每个经纪人的最后一行,其中包含所有替换后的值
  5. 这是SQL Fiddle

答案 1 :(得分:0)

这有点困难,因为它需要不区分大小写(对于像iIitpT这样的事情)。通常,您只需使用UPPER(),但您希望保留其余列的大小写。它还必须替换许多不同的“不正确”字母。最后,你不需要拾取xxxtpt之类的东西,如果你不能用空格去(因为它可能在开头或结尾),这很难。我不确定你的最终目标是什么。我能想到两个:

  1. 您只需要一个Query来正确格式化结果。
  2. 您希望更新包含此内容的任何值。
  3. 无论哪种方式,这是我能提出的最简单的解决方案(虽然是补救措施)。您必须考虑所有不正确的案例组合(例如:tpt, tpT, tPt, tPT, Tpt, TPt)。这是一种蛮力,但由于缺乏时间和简单性(特别是如果只是少数情况),这将有效:

    代码:

    Select
    Trim(
      Replace(
      Replace(
      Replace(
      Replace(
      Replace(
      --note the ' ' are added so we can search for a isolated instance of
      --' tpt ' at the beginning or end of lines, as well as inbetween
      -- these space get Trim()'d at in the end of processing everything.
      Replace(' ' || test_t.text || ' ', ' tpt ', ' TPT ')
                                       , ' tpT ', ' TPT ')
                                       , ' tPt ', ' TPT ')
                                       --etc...
                                       , ' iii ', ' III ')
                                       --etc...
                                       , ' Iii ', ' III ')
                                       , ' IIi ', ' III ')
    )
    as text
    
    --poor man's way of creating test tables
    From
    (
        Select 'tpt Broker' as text From dual UNION ALL
        Select 'Mark iii'   as text From dual UNION ALL
        Select 'Davidtpt'   as text From dual 
    ) test_t
    

    结果:

    TPT Broker
    Mark III
    Davidtpt
    

    这几乎是穷人的方式。如果这是一个长期问题,我确信有更好的解决方案,但如果您的数据清理很容易,这可能会有效。您也可以尝试使用REGEXP_REPLACEINSTR的某些组合。如果我想到更好的东西,我会更新这篇文章。

    编辑:

    Oi,我知道必须有更好的方法。使用REGEXP_REPLACE可以简化这一过程。我无法让“不区分大小写”的查询工作(可能忽略了一些东西)。相同的方法,但这是一个实际的体面解决方案:

    Select
        Trim(
            REGEXP_REPLACE(
            REGEXP_REPLACE(
              ' ' || text || ' '  ,  ' [tT][pP][tT] ', ' TPT ')
                                  ,  ' [iI][iI][iI] ', ' III ')
            ) as text
    From
    (
        Select 'tPt Broker' as text From dual UNION ALL
        Select 'Mark iii'   as text From dual UNION ALL
        Select 'Davidtpt'   as text From dual 
    ) test_t