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.