查找字符串中的特定单词,从单词开头返回前4个字符

时间:2019-01-29 15:06:29

标签: sql db2

我需要添加一个计算字段,以在字符串中找到单词“ Month”,然后返回之前的立即数字字符。

此评估需要完成的字段是FIELD12。

此字段中可能有很多字符串格式。重要的是,当单词month出现时,紧接其前面将至少有一个数字。

例如

  • 6个月促销
  • 120个月的12.99%
  • 减少12个月

依此类推

以下代码当前运行良好。我已删除敏感信息。

SELECT  SAMPLETABLE.CRED_CARD_ID  
    , SAMPLETABLE.LN_ORIG_DT  
    , SAMPLETABLE.ACCT_STAT_DESC  
    , SAMPLETABLE.CURR_BAL_AMT  
    , SAMPLETABLE.TRM_MTH_NBR  
    , SAMPLETABLE.PROMO_END_DT  
    , SAMPLETABLE.PURCH_WNDW_END_DT  
    , SAMPLETABLE.PROMO_TRM_TXT  
    , SAMPLETABLE.FIELD12

FROM 
    DB.SAMPLETABLE SAMPLETABLE
    INNER JOIN
    (SELECT  MAX(SAMPLETABLE_1.BI_DATA_AS_OF_DT) AS AS_OF_DT
    FROM DB.SAMPLETABLE SAMPLETABLE_1) Subquery
    ON (SAMPLETABLE.BI_DATA_AS_OF_DT = Subquery.AS_OF_DT) 
WHERE (SAMPLETABLE.ACCT_STAT_DESC = 'Open')

5 个答案:

答案 0 :(得分:1)

我通常只需在字符串的末尾添加'Month'即可解决此问题。不过,您更可能希望使用case表达式:

select (case when Field12 like '%Month%' then SUBSTR(FIELD12, LOCATE('Month', FIELD12), -4) end)

答案 1 :(得分:1)

DB2正则表达式示例。

select 
  t.FIELD12
, xmlcast(xmlquery('let $r := fn:replace($s, ".* (\d+) +month.*", "$1", "i") return if ($r castable as xs:integer) then xs:integer($r) else ()' passing ' '||t.FIELD12 as "s") as int) number
from table (values
  '4.99% for 6 Months until End'
, 'Equal Payments for 120 months'
, 'Equal Payments for 24 months'
, '1 month'
, 'wrong string'
, 'unknown number of months'
) t (FIELD12);

结果是:

FIELD12                         NUMBER
----------------------------    ------
4.99% for 6 Months until End         6
Equal Payments for 120 months      120
Equal Payments for 24 months        24
1 month                              1
wrong string                         -
unknown number of months             -

在您的情况下应该是这样的:

SELECT  SAMPLETABLE.CRED_CARD_ID  
    , SAMPLETABLE.LN_ORIG_DT  
    , SAMPLETABLE.ACCT_STAT_DESC  
    , SAMPLETABLE.CURR_BAL_AMT  
    , SAMPLETABLE.TRM_MTH_NBR  
    , SAMPLETABLE.PROMO_END_DT  
    , SAMPLETABLE.PURCH_WNDW_END_DT  
    , SAMPLETABLE.PROMO_TRM_TXT  
    , SAMPLETABLE.FIELD12
    , xmlcast(xmlquery('let $r := fn:replace($s, ".* (\d+) +month.*", "$1", "i") return if ($r castable as xs:integer) then xs:integer($r) else ()' passing ' '||SAMPLETABLE.FIELD12 as "s") as int) as number
FROM 
    DB.SAMPLETABLE SAMPLETABLE
    INNER JOIN
    (SELECT  MAX(SAMPLETABLE_1.BI_DATA_AS_OF_DT) AS AS_OF_DT
    FROM DB.SAMPLETABLE SAMPLETABLE_1) Subquery
    ON (SAMPLETABLE.BI_DATA_AS_OF_DT = Subquery.AS_OF_DT) 
WHERE (SAMPLETABLE.ACCT_STAT_DESC = 'Open');

fn:replace函数接受SAMPLETABLE.FIELD12作为第一个参数。第二个参数是正则表达式模式,与传递的列值进行比较。模式.* (\d+) +month.*子元素的含义:

.*-零个或多个字符

-一个空格

(\d+)-一个或多个数字;我们将其用()包围起来,以便以后参考

+-一个或多个空格

month-字符串常量

.*-零个或多个字符

如果列值遵循此模式,则整个值将替换为模式中的第一个(也是唯一的)组值(由()包围,我们在此用$1引用)函数的第3个参数)。 如果不是,则列值保持不变。 最后,我们尝试使用xpath表达式将替换后的值转换为int。如果这样的转换不成功,它将返回NULL

答案 2 :(得分:0)

如果您的Db2版本支持REGEXP函数(例如,在LUW的Db2 11.1上),您会发现REGEXP_SUBSTR https://www.ibm.com/support/knowledgecenter/en/SS6NHC/com.ibm.swg.im.dashdb.sql.ref.doc/doc/r0061497.html更灵活。例如

SELECT 
  T.FIELD12
, REGEXP_SUBSTR(FIELD12,'(\d{1,4})\s+month',1,1,'i',1) AS REGEX_SOLUTION
, SUBSTR(FIELD12,NULLIF(LOCATE('months',lower(FIELD12)),0)-4,4) AS SUBSTR_SOLUTION
FROM TABLE (VALUES
  '4.99% for 6 Months until End'
, 'Equal Payments for 120 months adn 12 months'
, 'Equal Payments for 24 months'
, '1 month'
, 'wrong string'
, 'unknown number of months'
) T (FIELD12);

给予

 FIELD12                                        REGEX_SOLUTION  SUBSTR_SOLUTION
 -------------------------------------------    --------------  ---------------
 4.99% for 6 Months until End                   6               r 6 
 Equal Payments for 120 months adn 12 months    120             120 
 Equal Payments for 24 months                   24               24 
 1 month                                        1               NuLL
 wrong string                                   NuLL            NuLL
 unknown number of months                       NuLL             of 

答案 3 :(得分:0)

抑制索引为负的情况以解决超出范围的错误

select 
SUBSTR(FIELD12,LOCATE('Month', FIELD12),-4)
from mytable

where LOCATE('Month', FIELD12) > 4

答案 4 :(得分:0)

谢谢@ Mark-Barinstein !!!下面的语句非常有效。

xmlcast(xmlquery('let $ r:= fn:replace($ s,“。*(\ d +)+ month。*”,“ $ 1”,“ i”)返回if($ r castable as xs:整数),然后xs:integer($ r)else()'传递''|| SAMPLETABLE.FIELD12为“ s”)作为int)作为数字

相关问题