PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come unire tabelle su regex

Come ha già menzionato @Milen regexp_matches() è probabilmente la funzione sbagliata per il tuo scopo. Vuoi una semplice corrispondenza di espressioni regolari (~ ) . In realtà, l'operatore LIKE (~~ ) sarà più veloce :

Presumibilmente il più veloce con 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

Inoltre, vuoi solo mnc.code di esattamente 3 caratteri.

Con regexp

Potresti scrivi lo stesso con le espressioni regolari ma sarà sicuramente più lento. Ecco un esempio funzionante vicino al tuo originale:

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

Ciò richiede anche msg.src_addr e msg.dst_addr essere NOT NULL .

La seconda query mostra come il controllo aggiuntivo length(mnc.code) = 3 può entrare nel JOIN condizione o un WHERE clausola. Stesso effetto qui.

Con regexp_matches()

Potresti fallo funzionare con 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
    )

Ma sarà lento in confronto, o almeno così presumo.

Spiegazione:
La tua espressione regexp_matches() restituisce solo un array di tutte le sottostringhe catturate della prima incontro. Poiché catturi solo una sottostringa (una coppia di parentesi nel tuo pattern), otterrai esclusivamente array con un elemento .

Ottieni tutte le corrispondenze con l'opzione "globale" aggiuntiva 'g' - ma in più righe. Quindi è necessaria una sottoselezione per testarli tutti (o aggregarli). Mettilo in un EXISTS - semi-unisciti e arrivi a quello che volevi.

Forse puoi riferire con un test delle prestazioni di tutti e tre?Usa EXPLAIN ANALYZE per quello.