sql >> Database >  >> RDS >> PostgreSQL

Tabellen samenvoegen op regex

Zoals @Milen al zei regexp_matches() is waarschijnlijk de verkeerde functie voor uw doel. U wilt een eenvoudige regelmatige expressieovereenkomst (~ ) . Eigenlijk is de LIKE-operator (~~ ) zal sneller zijn :

Vermoedelijk de snelste met LIKE

SELECT msg.message
      ,msg.src_addr
      ,msg.dst_addr
      ,mnc.name
FROM   mnc
JOIN   msg ON msg.src_addr ~~ ('%38' || mnc.code || '%')
           OR msg.dst_addr ~~ ('%38' || mnc.code || '%')
WHERE  length(mnc.code) = 3

Daarnaast wil je alleen mnc.code van precies 3 tekens.

Met regexp

Je zou schrijf hetzelfde met reguliere expressies, maar het zal zeker langzamer zijn. Hier is een werkend voorbeeld dat dicht bij uw origineel ligt:

SELECT msg.message
      ,msg.src_addr
      ,msg.dst_addr
      ,mnc.name
FROM   mnc
JOIN   msg ON (msg.src_addr || '+' || msg.dst_addr) ~ (38 || mnc.code)
           AND length(mnc.code) = 3

Dit vereist ook msg.src_addr en msg.dst_addr te zijn NOT NULL .

De tweede vraag laat zien hoe de extra controle length(mnc.code) = 3 kan naar de JOIN . gaan voorwaarde of een WHERE clausule. Hier hetzelfde effect.

Met regexp_matches()

Je zou laat dit werken met regexp_matches() :

SELECT msg.message
      ,msg.src_addr
      ,msg.dst_addr
      ,mnc.name
FROM   mnc
JOIN   msg ON EXISTS (
    SELECT * 
    FROM   regexp_matches(msg.src_addr ||'+'|| msg.dst_addr, '38(...)', 'g') x(y)
    WHERE  y[1] = mnc.code
    )

Maar het zal in vergelijking traag zijn - althans dat neem ik aan.

Uitleg:
Uw regexp_matches()-expressie retourneert gewoon een array van alle vastgelegde subtekenreeksen van de eerste wedstrijd. Aangezien u slechts één substring vastlegt (één paar haakjes in uw patroon), krijgt u uitsluitend arrays met één element .

Je krijgt alle overeenkomsten met de extra "globaal" schakelaar 'g' - maar in meerdere rijen. Je hebt dus een subselectie nodig om ze allemaal te testen (of te aggregeren). Zet dat in een EXISTS - semi-join en je komt aan wat je wilde.

Misschien kun je terug rapporteren met een prestatietest van alle drie?Gebruik UITLEG ANALYSE daarvoor.



  1. Hoe de UPPER()-functie werkt in MySQL

  2. PHP/MySQL-groepsresultaten per kolom

  3. Probleem met lezen van Delphi SQL-datum

  4. Hoe bereken ik de grootte van tabellen in Oracle