Oracle
 sql >> база данни >  >> RDS >> Oracle

Как да преброим срещанията на разделител в низ, с изключение на тези в кавички

Първо елиминирайте ограниченото съдържание, пребройте след това:

regexp_count (
    regexp_replace (
        regexp_replace (
            i.data_record
          , '(^|,)"[^"]*"(,|$)'
          , '\1\2'
        )
      , '(^|,)"[^"]*"(,|$)'
      , '\1\2'
    )
  , ',' 
) 

Влагането на regexp_replace calls за съжаление е необходимо, за да се обработват правилно последователни полета, разделени с кавички:всяка разделителна запетая се консумира от модела на регулярен израз и по този начин няма да бъде взета под внимание за последващо съвпадение.

Regexen на Oracle не поддържа оператора look-head, който би бил естественият начин за справяне с тази ситуация.

Предвид удара на производителността на извикванията на regexp_... може би е по-добре да използвате

length(i.data_record) - length ( replace ( regexp_replace ( i.data_record, '(^|,)"[^"]*"(,|$)', '\1\2' ),',','' ) )

Предупреждение

Това решение не обработва dкавички в стойностите на полетата, които обикновено се представят като "" или \" .

Първият случай може да се третира елегантно:Вместо да се интерпретира "" вътре в поле, разделено с кавички, разглеждайте цялото съдържание на полето като съпоставяне на 1 или повече низове, разделени с dquote, които не съдържат dquotes. Въпреки че не бихте следвали този маршрут при обработката на данните (всички кавички ще бъдат загубени), можете да използвате тази перспектива за целите на броенето:

regexp_count (
    regexp_replace (
        regexp_replace (
            i.data_record
          , '(^|,)("[^"]*")+(,|$)'  -- changed
          , '\1\3'                  -- changed
        )
      , '(^|,)("[^"]*")+(,|$)'   -- changed
      , '\1\3'                   -- changed
    )
  , ',' 
) 

Тестови случаи

-- works
select regexp_count ( regexp_replace ( regexp_replace ( '1,"data,and more so","more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;
select regexp_count ( regexp_replace ( regexp_replace ( '1,"data,and more so",2,"more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;

select regexp_count ( regexp_replace ( regexp_replace ( '1,"""data"",and more so",2,"more data,and even more so"', '(^|,)("[^"]*")+(,|$)', '\1\3' ), '(^|,)("[^"]*")+(,|$)', '\1\3' ), ',' ) from dual;

-- fails
select regexp_count ( regexp_replace ( '1,"data,and more so","more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;
select regexp_count ( regexp_replace ( '1,"data,and more so",2,"more data,and even more so"', '(^|,)"[^"]*"(,|$)', '\1\2' ), ',' ) from dual;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Можем ли да имаме 2 различни зависимости на Oracle от 2 различни бази данни в едно приложение на asp.net

  2. TNS-12519 без максимален достигнат процес

  3. Сравнение на дати на Oracle в клауза where

  4. Времево клеймо на Oracle с прозрачен превод на стойностите на местната часова зона

  5. Oracle SELECT ТОП 10 записа