sql >> Database >  >> RDS >> Oracle

Vind alle overeenkomsten in een varchar2()

Geweldige vraag! Hier is een viool laat zien hoe u de overeenkomsten in een resultatenset kunt opvragen.

En hier is de lange uitleg voor het geval de vraag in de Fiddle niet klopt :)

Ik gebruik een tabel met de naam RegEx_Test met een kolom MyVal . Dit is de inhoud van de tabel:

MyVal
------------------------------
[A1][abc][B23][D123]a33[bx5]
[Z15][ax0][B0][F13]R3
[X215][A3A][J99]F33F33G24[43][R3]
[Z99][c1][F3][d33]3x24[Y3][f13]
[9a][D41][Q39][XX12]B27[T03][J12]

Je regexp is dit:\[[[:alpha:]][[:digit:]]{1,2}\] . Het is hetzelfde als in het andere antwoord, behalve met de POSIX :alpha: en :digit: indicatoren, die veiliger zijn in het geval van internationale karaktersets.

Eerst moet u het maximale aantal overeenkomsten op een regel weten. Gebruik REGEXP_COUNT hiervoor:

SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
  FROM Regex_Test

MAX(REGEXP_COUNT(My...
----------------------
                     6

Gebruik dat maximale aantal om een ​​"teller"-tabel te krijgen (dat is de SELECT ... FROM DUAL hieronder) en voeg een kruislings toe aan de tellertabel met een query die uw waarden ophaalt met behulp van REGEXP_SUBSTR . REGEXP_SUBSTR heeft een "occurrence" parameter en die zal de Counter . gebruiken :

SELECT
  MyVal,
  Counter,
  REGEXP_SUBSTR(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]', 1, Counter) Matched
FROM Regex_Test
CROSS JOIN (
   SELECT LEVEL Counter
   FROM DUAL
   CONNECT BY LEVEL <= (
     SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
     FROM Regex_Test)) Counters

Hier is een voorbeeldrun tegen mijn tafel (gedeeltelijke resultaten):

MyVal                              Counter Matched
---------------------------------- ------- -------
[9a][D41][Q39][XX12]B27[T03][J12]        1 [D41]
[9a][D41][Q39][XX12]B27[T03][J12]        2 [Q39]
[9a][D41][Q39][XX12]B27[T03][J12]        3 [T03]
[9a][D41][Q39][XX12]B27[T03][J12]        4 [J12]
[9a][D41][Q39][XX12]B27[T03][J12]        5
[9a][D41][Q39][XX12]B27[T03][J12]        6
[A1][abc][B23][D123]a33[bx5]             1 [A1]
[A1][abc][B23][D123]a33[bx5]             2 [B23]
[A1][abc][B23][D123]a33[bx5]             3
... and so on - total is 30 rows

Op dit punt heb je een resultatenset van individuele matches, plus nulls waarbij een rij minder dan het maximale aantal matches had. De wedstrijden hebben nog steeds hun omringende haakjes. Omring het geheel met een buitenste query die de nulls eruit filtert en de haakjes verwijdert, en je hebt je definitieve lijst:

SELECT SUBSTR(Matched, 2, LENGTH(Matched)-2) FROM (
  SELECT
    MyVal,
    Counter,
    REGEXP_SUBSTR(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]', 1, Counter) Matched
  FROM Regex_Test
  CROSS JOIN (
     SELECT LEVEL Counter
     FROM DUAL
     CONNECT BY LEVEL <= (
       SELECT MAX(REGEXP_COUNT(MyVal, '\[[[:alpha:]][[:digit:]]{1,2}\]'))
       FROM Regex_Test)) Counters
) WHERE Matched IS NOT NULL

Dit is de zoekopdracht die op de Fiddle staat en kan in een andere zoekopdracht worden gebruikt.



  1. Hoe MySQL-processen te tonen

  2. MySQL ALS NULL ANDERS

  3. SQL Server 2008 Rij Tijdstempels invoegen en bijwerken

  4. Database-sharding versus partitionering