sql >> Database teknologi >  >> RDS >> Oracle

Sådan tælles forekomster af separator i strenge, undtagen dem i anførselstegn

Fjern først det afgrænsede indhold, tæl bagefter:

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

Indlejringen af ​​regexp_replace opkald er desværre nødvendige for at håndtere på hinanden følgende felter afgrænset af anførselstegn korrekt:ethvert adskillelseskomma forbruges af regexp-mønsteret og vil derfor ikke blive taget i betragtning for det efterfølgende match.

Oracles regexen understøtter ikke lookahead-operatøren, hvilket ville være den naturlige måde at håndtere denne situation på.

I betragtning af præstationshittet af regexp_... opkald, er du måske bedre stillet til at bruge

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

Advarsel

Denne løsning håndterer ikke dcitater inden for feltværdier, som normalt er repræsenteret som "" eller \" .

Førstnævnte sag kan håndteres elegant:I stedet for at fortolke en "" inde i et anførselssepareret felt skal du betragte hele feltindholdet som en sidestilling af 1 eller flere anførselsseparerede strenge, der ikke indeholder anførselstegn. Selvom du ikke ville følge denne rute i behandlingen af ​​dataene (alle anførselstegn ville gå tabt), kan du bruge dette perspektiv for at tælle:

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

Testcases

-- 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. SQL Server - parametersniffing

  2. Hibernate + ON DUPLICATE KEY logik

  3. Fejl:Dubleret indtastning '0' for nøglen 'PRIMARY'

  4. Sådan bruges en ringdatastruktur i vinduesfunktioner