【问题标题】:Tricky use of substring子字符串的巧妙使用
【发布时间】:2011-05-10 16:50:45
【问题描述】:

我的问题是关于一个名为 contract_nm varchar2(14) 的字段。我需要从中获取 3 个不同的值,使用该字段来获取 where 子句的过滤器。

这里是示例数据以及数据可能有多长,9 或 10 或 11,现在不能再多了。

CONTRACT_NM               LENGTH(CONTRACT_NM)
F.US.WZ10                          9
F.US.WZ11                          9
F.US.WZ12                          9
F.US.RBZ10                         10
F.US.RBZ11                         10
F.US.RBZ12                         10
F.US.ZWAZ10                     11
F.US.ZWAZ11                     11
F.US.ZWAZ12                     11
etc

1) 我需要显示contract_nm的最后3个字符。

2) 检查contract_nm的最后3个字符,看第一个字母是否是下面的一个,那么接下来的2个字母是MONTH和YEAR,DAY默认为第一天这个月。我需要像日期一样显示,因为它会进入日期字段。

Trade Months (Terms):
F              January                                
G             February                              
H             March                   
J              April                       
K             May
M       June                           
N             July
Q             August
U             September
V             October
X             November
Z       December

3)这在书面上有点难以解释,我会尽力希望你能理解我!读取 contract_nm 数据,忽略前五个字符(F.US.),然后忽略最后三个字符,即 Z11。现在,我们正在使用的是中间的 1 个字符(9 长度)或 2 个字符(10 长度)或 3 个字符(11 长度)的数据,请参阅下面的数据。如果 1 个字符,则显示该字母,否则,如果 2 个字符,则检查第 2 个字母,如果不是“E”或“A”或“T”,则显示两个字母,否则仅显示第一个字母。如果是 3 个字符,则显示前 2 个字符。

4) 我的 where 子句需要一个过滤器来读取 contract_nm 数据,忽略前五个字符 (F.US.),然后忽略最后三个字符,即 Z11。现在,我们正在使用的是中间的 1 个字符(9 长度)或 2 个字符(10 长度)或 3 个字符(11 长度)的数据,请参阅下面的数据。如果是 2 个字符,则检查第 2 个字母,如果不是“E”或“T”则不提取数据,否则执行。 else if 3个字符,然后检查第3个字母如果不是'E'或'T'那么不要拉数据,否则就做。

【问题讨论】:

    标签: oracle substring


    【解决方案1】:

    专注于如何将 CONTRACT_NM 分解为您需要的部分。然后创建一个视图,以便您可以将每个部分视为一列。应用您的各种条件和转换应该很简单。

    您似乎总是忽略前 5 个字符,所以把它们删掉。

    SELECT SUBSTR( contract_nm, 5, LENGTH(contract_nm)-8 ) flags,
           SUBSTR( contract_nm, -3, 1 ) month_flag,
           SUBSTR( contract_nm, -2 ) year
      FROM table
    

    1) month_flag||year.
    2)

    TO_DATE(
            CASE month_flag WHEN 'F' THEN 'JAN' WHEN 'G' THEN 'FEB' ... END || year,
            'MONRR'
            )
    

    3)

    CASE WHEN LENGTH(flags) = 3
              THEN SUBSTR(flags,1,2)
            WHEN LENGTH(flags) = 2 AND SUBSTR(flags,2,1) NOT IN ('E','A','T')
              THEN flags
            ELSE SUBSTR(flags,1,1)
    

    4) 与 #3 非常相似

    【讨论】:

      【解决方案2】:

      尝试以下方法:

      问题一:

        contract_nm_month_year := substr(contract_nm, -3);
      

      问题2:

        contract_date := CASE substr(contract_nm, -3, 1)
                            WHEN 'F' THEN TO_DATE('01-JAN-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'G' THEN TO_DATE('01-FEB-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'H' THEN TO_DATE('01-MAR-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'J' THEN TO_DATE('01-APR-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'K' THEN TO_DATE('01-MAY-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'M' THEN TO_DATE('01-JUN-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'N' THEN TO_DATE('01-JUL-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'Q' THEN TO_DATE('01-AUG-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'U' THEN TO_DATE('01-SEP-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'V' THEN TO_DATE('01-OCT-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'X' THEN TO_DATE('01-NOV-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            WHEN 'Z' THEN TO_DATE('01-DEC-' || SUBSTR(contract_nm, -2), 'DD-MON-RR');
                            ELSE NULL;
                          END;
      

      问题 3:

        display_3 := CASE length(contract_nm)
                       WHEN 9 THEN SUBSTR(contract_nm, 6, 1);
                       WHEN 10 THEN
                          CASE SUBSTR(contract_nm, 7, 1)
                            WHEN 'E' THEN SUBSTR(contract_nm, 6, 1);
                            WHEN 'A' THEN SUBSTR(contract_nm, 6, 1);
                            WHEN 'T' THEN SUBSTR(contract_nm, 6, 1);
                            ELSE SUBSTR(contract_nm, 6, 2);
                          END;
                       WHEN 11 THEN SUBSTR(contract_nm, 6, 2)
                     END;
      

      问题 4:

        WHERE CASE length(contract_nm)
                WHEN 9 THEN 0 -- never pull data for contract length = 9
                WHEN 10 THEN
                  CASE SUBSTR(contract_nm, 7, 1)
                    WHEN 'E' THEN 1
                    WHEN 'T' THEN 1
                    ELSE 0
                  END
                WHEN 11 THEN
                  CASE SUBSTR(contract_nm, 8, 10
                    WHEN 'E' THEN 1
                    WHEN 'T' THEN 1
                    ELSE 0
                  END
                ELSE 0
              END = 1;
      

      分享和享受。

      【讨论】:

        【解决方案3】:

        1) 我需要显示最后 3 个 contract_nm 的字符。

        使用 SUBSTR(contract_nm, -3)

        关于 Q2,请使用 CASE 表达式,例如:

        CASE SUBSTR(contract_nm, -3, 1)
          WHEN 'F' THEN TO_DATE('JAN'||SUBSTR(contract_nm, -2), 'MONRR')
          WHEN 'G' THEN TO_DATE('FEB'||SUBSTR(contract_nm, -2), 'MONRR')
          ...etc.
          END
        

        【讨论】:

          猜你喜欢
          • 2022-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-10
          • 2015-03-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多