Regexp_Substr для точки с запятой в запросе для ORACLE DB - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть REGEXP_SUBSTR для разделения точки с запятой, но проблема в том, что если между двумя точками с запятой нет данных, то следующие данные смещаются на один столбец раньше.

Вот пример ниже.

Данные в столбце БД Oracle

ColumnXYZ
A;;B

Теперь мой запрос

SELECT REGEXP_SUBSTR(COLUMNXYZ, '[^;]+', 1, 1) as COL1,
       REGEXP_SUBSTR(COLUMNXYZ, '[^;]+', 1, 2) as COL2,
       REGEXP_SUBSTR(COLUMNXYZ, '[^;]+', 1, 3) as COL3,
FROM TABLE T

После выполнения показываются данные ниже

COL1  COL2  COl3
A      B    null

но мне нужен вывод в формате ниже, так как между двумя точками с запятой нет значения.

COL1   COL2  COL3  
A      null  B

Ответы [ 3 ]

0 голосов
/ 13 февраля 2019

Это должно работать:

WITH cte AS (
    SELECT 'A;B;C' AS col FROM DUAL UNION
    SELECT 'A;B;' AS col FROM DUAL UNION
    SELECT ';B;C' AS col FROM DUAL UNION
    SELECT 'A;;C' AS col FROM DUAL UNION
    SELECT 'A;;' AS col FROM DUAL UNION
    SELECT ';B;' AS col FROM DUAL UNION
    SELECT ';;C' AS col FROM DUAL UNION
    SELECT ';;' FROM DUAL
)
SELECT col
    , REGEXP_SUBSTR(col, '([^;]*)(;|$)', 1, 1, '', 1) AS col1
    , REGEXP_SUBSTR(col, '([^;]*)(;|$)', 1, 2, '', 1) AS col2
    , REGEXP_SUBSTR(col, '([^;]*)(;|$)', 1, 3, '', 1) AS col3
FROM cte

Шаблон ([^;]*)(;|$) соответствует нулю или нескольким точкам с запятой, за которыми следует точка с запятой или конец строки.Группировка используется для преобразования каждого совпадения в два подспички, например A; становится A и ;.

0 голосов
/ 13 февраля 2019

Вы можете использовать replace с аргументом '; ;', а затем trim

with t1 as
(select replace('A;;B',';;','; ;') as str from dual 
),
     t2(col1,col2,col3) as
(
 select regexp_substr(str, '[^;]+', 1, 1),
        trim(regexp_substr(str, '[^;]+', 1, 2)),
        regexp_substr(str, '[^;]+', 1, 3) 
   from t1
)   
select * from t2;

  COL1  COL2  COL3
  ----  ----  ----
  A     null  B

Редактировать в зависимости от вашего комментария:

Если вы хотите получить построчный результат, рассмотрите следующий запрос:

with t1 as
 (select replace('A;;B',';;','; ;') as str from dual)
   select trim(regexp_substr(str, '[^;]+', 1, level))
       as "Result String"
     from t1
    cross join dual
  connect by level <= length(regexp_replace(str, ';',''));

Result String
-------------
A

B
0 голосов
/ 13 февраля 2019
  SELECT   ROWNUM AS num_row,
           REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', '; ;'),';;','; ;'), '[^;]+', 1, LEVEL) AS par_value
  FROM     dual
  CONNECT  BY REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', '; ;'),';;','; ;'), '[^;]+', 1, LEVEL) IS NOT NULL

Или, если вам нужен пустой столбец:

SELECT  num_row,
        CASE
          WHEN par_value = '#$N#$' THEN NULL
          ELSE par_value
        END as par_value
FROM    (
          SELECT   ROWNUM AS num_row,
                   REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', ';#$N#$;'),';;','; ;'), '[^;]+', 1, LEVEL) AS par_value
          FROM     dual
          CONNECT  BY
                   REGEXP_SUBSTR(REPLACE(REPLACE('A;;B', ';;', ';#$N#$;'),';;','; ;'), '[^;]+', 1, LEVEL) IS NOT NULL
        )

$ N # $ - пример значения для нулевого

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...