sql >> Base de Datos >  >> RDS >> PostgreSQL

Cómo unir tablas en expresiones regulares

Como @Milen ya mencionó regexp_matches() es probablemente la función incorrecta para su propósito. Desea una simple coincidencia de expresiones regulares (~ ) . En realidad, el operador LIKE (~~ ) será más rápido :

Presumiblemente más rápido 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

Además, solo desea mnc.code de exactamente 3 caracteres.

Con expresión regular

podrías escriba lo mismo con expresiones regulares, pero definitivamente será más lento. Aquí hay un ejemplo de trabajo cercano a su original:

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

Esto también requiere msg.src_addr y msg.dst_addr ser NOT NULL .

La segunda consulta demuestra cómo la comprobación adicional length(mnc.code) = 3 puede ir a JOIN condición o un WHERE cláusula. Mismo efecto aquí.

Con regexp_matches()

podrías haz que esto funcione 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
    )

Pero será lento en comparación, o eso supongo.

Explicación:
Su expresión regexp_matches() solo devuelve una matriz de todas las subcadenas capturadas de la primera juego. Como solo captura una subcadena (un par de corchetes en su patrón), obtendrá exclusivamente matrices con un elemento .

Obtienes todas las coincidencias con el interruptor adicional "globalmente" 'g' - pero en varias filas. Por lo tanto, necesita una subselección para probarlos todos (o agregados). Pon eso en un EXISTS - semi-unir y llegas a lo que querías.

Tal vez pueda informar con una prueba de rendimiento de los tres? Use EXPLAIN ANALYZE por eso.