Oracle使用可选字段和重复值格式化csv地址

时间:2017-02-03 13:31:23

标签: sql regex oracle

我有一个Oracle PLSQL函数,它以逗号分隔格式返回一个地址(从sql调用),例如:

, 7 Hawaii Street, Windhoek, Windhoek, 9000, , , , , 

地址存储在许多不同的样式中,因此字段可能是空白的(即使是地址行1,例如,如果该人不住在公寓中)。

每个字段前还有一个可选的前导空格。

我想以下列格式打印输出,而

之间没有空行
7 Hawaii Street,Windhoek,Windhoek,9000

甚至

7 Hawaii Street,Windhoek,9000

我的尝试如下(删除每个字段前的空格并删除双逗号;但完全失去温得和克):

select ltrim
         (
            replace
            (
               replace
               (
                  regexp_replace
                  (
                     xxpay_bi_util.get_address   -- varchar2
                     (
                         p_person_id       => papf2.person_id,   -- in number
                         p_effective_date  => trunc(nvl(fnd_date.canonical_to_date(:EFFECTIVE_DATE), sysdate)),   -- in date
                         p_type            => 'full',            -- in varchar2
                         p_include_null    => 'Y',
                         p_include_country => 'N'
                     ),
                     '([^,]+)(,[ ]*\1)+'
                  ),
                  ',,', ','
               ),
               ', ', ','
            ),
            ','
         )  csv

任何人都可以帮我解决这个问题,这样它就不会松开温得和克了吗?

3 个答案:

答案 0 :(得分:1)

这应该有效:

trim( ',' from regexp_replace(str, '(,\s*)+', ','))

它只用一个逗号替换每个出现的(一个或多个逗号,每个逗号后跟零个或多个空格)。然后它会修剪前导和尾随逗号(如果有的话)。

据说,正如我在评论中提到的那样,字符串很可能是从基础数据开始构建的。 那个首先构建字符串是应该修复的,那么你就不会遇到这个问题。

答案 1 :(得分:0)

试试这个

WITH t AS 
    (SELECT LEVEL AS Item_no, TRIM(REGEXP_SUBSTR(', 7 Hawaii Street, Windhoek, Windhoek, 9000, , , , , ', '[^,]+', 1, LEVEL)) AS item 
    FROM dual
    CONNECT BY REGEXP_SUBSTR(', 7 Hawaii Street, Windhoek, Windhoek, 9000, , , , , ', '[^,]+', 1, LEVEL) IS NOT NULL)
SELECT listagg(item, ',') WITHIN GROUP (ORDER BY Item_no)
FROM t
WHERE item IS NOT NULL;

答案 2 :(得分:0)

REGEXP_REPLACE(
  REGEXP_REPLACE(
    ', 7 Hawaii Street, Windhoek, Windhoek, 9000, , , , , ',
    '\s*,\s*',
    ','
  ),
  '^,+|,+$|(,),+',
  '\1'
)

<强>输出

7 Hawaii Street,Windhoek,Windhoek,9000

摆脱重复

WITH addresses ( address ) AS (
  SELECT ', 7 Hawaii Street, Windhoek, Windhoek, Windhoek County, Windhoek County, 9000, , , , , ' FROM DUAL
)
SELECT LISTAGG( address_part, ',' ) WITHIN GROUP ( ORDER BY lvl ) AS address
FROM   (
  SELECT ID,
         ROW_NUMBER() OVER ( PARTITION BY id ORDER BY ROWNUM ) AS lvl,
         t.column_value AS address_part,
         CASE WHEN LAG( t.column_value ) OVER ( PARTITION BY id ORDER BY ROWNUM )
                   = t.column_value THEN 1 ELSE 0 END AS is_duplicate
  FROM   ( SELECT ROWID AS id,
                  REGEXP_REPLACE(
                    REGEXP_REPLACE( address, '\s*,\s*', ',' ),
                    '^,+|,+$|(,),+',
                    '\1'
                  ) AS address
           FROM   addresses
         ) a
         CROSS JOIN
         TABLE(
           CAST(
             MULTISET(
               SELECT REGEXP_SUBSTR( a.address, '[^,]+', 1, LEVEL )
               FROM   DUAL
               CONNECT BY LEVEL <= REGEXP_COUNT( a.address, '[^,]+' )
             ) AS SYS.ODCIVARCHAR2LIST
           )
         ) t
)
WHERE  is_duplicate = 0
GROUP BY id;

<强>输出

ADDRESS
---------------------------------------------
7 Hawaii Street,Windhoek,Windhoek County,9000