sql >> Database >  >> RDS >> Oracle

string splitsen in meerdere rijen

Van jouw commentaar tot het antwoord van @PrzemyslawKruglej

Het belangrijkste probleem is de interne zoekopdracht met connect by , het genereert een verbazingwekkende hoeveelheid rijen

Het aantal gegenereerde rijen kan worden verminderd met de volgende aanpak:

/* test table populated with sample data from your question */
SQL> create table t1(str) as(
  2    select 'a;b;c'  from dual union all
  3    select 'b;c;d'  from dual union all
  4    select 'a;c;d'  from dual
  5  );
Table created

--  number of rows generated will solely depend on the most longest 
--  string. 
--  If (say) the longest string contains 3 words (wont count separator `;`)
--  and we have 100 rows in our table, then we will end up with 300 rows 
--  for further processing , no more.
with occurrence(ocr) as( 
  select level 
    from ( select max(regexp_count(str, '[^;]+')) as mx_t
             from t1 ) t
    connect by level <= mx_t 
)
select count(regexp_substr(t1.str, '[^;]+', 1, o.ocr)) as generated_for_3_rows
  from t1
 cross join occurrence o;

Resultaat:Voor drie rijen waarvan de langste uit drie woorden bestaat, genereren we 9 rijen :

GENERATED_FOR_3_ROWS
--------------------
                  9

Laatste vraag:

with occurrence(ocr) as( 
  select level 
    from ( select max(regexp_count(str, '[^;]+')) as mx_t
             from t1 ) t
    connect by level <= mx_t 
)
select res
     , count(res) as cnt
  from (select regexp_substr(t1.str, '[^;]+', 1, o.ocr) as res
          from t1
         cross join occurrence o)
 where res is not null
 group by res
 order by res;

Resultaat:

RES          CNT
----- ----------
a              2
b              2
c              3
d              2

SQLFIddle-demo

Lees meer over regexp_count()(11g en hoger) en regexp_substr() reguliere expressiefuncties.

Opmerking: Reguliere expressiefuncties zijn relatief duur om te berekenen, en als het gaat om het verwerken van een zeer grote hoeveelheid gegevens, kan het de moeite waard zijn om over te schakelen naar een gewone PL/SQL. Hier is een voorbeeld.



  1. Verzamelmethode:DELETE-procedure in Oracle Database

  2. Hoe kan ik inloggen en de duurste zoekopdrachten vinden?

  3. SetDate gebruiken in PreparedStatement

  4. Milliseconden in mijn DateTime-wijzigingen wanneer opgeslagen in SQL Server