sql >> Databáze >  >> RDS >> Oracle

Jak počítat výskyty oddělovače v řetězci kromě těch v uvozovkách

Nejprve odstraňte ohraničený obsah a poté počítejte:

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

Vnoření regexp_replace volání je bohužel nezbytné pro správné zpracování po sobě jdoucích polí oddělených uvozovkami:jakákoliv oddělovací čárka je spotřebována vzorem regulárních výrazů, a proto nebude při následné shodě brána v úvahu.

Regexeny Oracle nepodporují dopředný operátor, což by byl přirozený způsob řešení této situace.

Vzhledem k výkonu volání regexp_... by možná bylo lepší použít

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

Upozornění

Toto řešení nezpracovává dquotes v rámci hodnot polí, které jsou obvykle reprezentovány jako "" nebo \" .

První případ lze vyřešit elegantně:Místo interpretace "" uvnitř pole s uvozovkami považujte obsah celého pole vedle sebe 1 nebo více řetězců oddělených dquote, které neobsahují dquote. I když byste se při zpracování dat neřídili touto cestou (všechny dquotes by byly ztraceny), můžete použít tuto perspektivu kvůli počítání:

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

Testovací případy

-- 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. Zobrazovat názvy všech omezení pro tabulku v Oracle SQL

  2. mysql fulltext MATCH,PROTI vrací 0 výsledků

  3. Smazat pomocí Join v Oracle SQL Query

  4. Jak používat Top with Ties v SQL Server - SQL Server / TSQL výukový program, část 114