2009-09-06 9 views
36

Tengo 2 tablas, digamos la tabla A y la tabla B y deseo realizar una combinación, pero la condición coincidente tiene que ser donde una columna de A 'es como' una columna de B, lo que significa que todo puede venir antes o después del columna en B:cómo usar un me gusta con una combinación en sql?

por ejemplo: si la columna en A es 'foo'. Entonces la unión coincidiría si la columna en B es: 'fooblah', 'somethingfooblah', o simplemente 'foo'. Sé cómo usar los comodines en una declaración estándar similar, pero estoy confundido al hacer una unión. ¿Esto tiene sentido? Gracias.

Respuesta

16

En MySQL podría intentar:

SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%');

Por supuesto, esto sería una consulta masivamente ineficiente porque haría un escaneo completo de tabla.

Actualización: He aquí una prueba de


create table A (MYCOL varchar(255)); 
create table B (MYCOL varchar(255)); 
insert into A (MYCOL) values ('foo'), ('bar'), ('baz'); 
insert into B (MYCOL) values ('fooblah'), ('somethingfooblah'), ('foo'); 
insert into B (MYCOL) values ('barblah'), ('somethingbarblah'), ('bar'); 
SELECT * FROM A INNER JOIN B ON B.MYCOL LIKE CONCAT('%', A.MYCOL, '%'); 
+-------+------------------+ 
| MYCOL | MYCOL   | 
+-------+------------------+ 
| foo | fooblah   | 
| foo | somethingfooblah | 
| foo | foo    | 
| bar | barblah   | 
| bar | somethingbarblah | 
| bar | bar    | 
+-------+------------------+ 
6 rows in set (0.38 sec) 
+1

Gracias ... ¿Cómo lograría la misma funcionalidad pero la haría más eficiente? –

+0

Así es como lo harías. Si necesita que sea más eficiente, puede indexar el campo MYCOL en la tabla B. –

+0

Si usa el tipo de tabla MyISAM, puede intentar con un índice de texto completo y ver si eso ayuda. En general, sin embargo, la búsqueda de texto completo no es una fortaleza de MySQL. Si la búsqueda de texto completo es una parte central de su aplicación, considere algo como Apache Lucene - http://lucene.apache.org/java/docs/ – Asaph

63

Usando INSTR:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON INSTR(b.column, a.column) > 0 

utilizando como:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE '%'+ a.column +'%' 

utilizando como, con CONCAT:

SELECT * 
    FROM TABLE a 
    JOIN TABLE b ON b.column LIKE CONCAT('%', a.column ,'%') 

cuenta que en todas las opciones, es probable que desea conducir los valores de columna a mayúsculas antes de comparar a asegurar que está recibiendo partidos sin preocuparse de mayúsculas y minúsculas:

SELECT * 
    FROM (SELECT UPPER(a.column) 'ua' 
     TABLE a) a 
    JOIN (SELECT UPPER(b.column) 'ub' 
     TABLE b) b ON INSTR(b.ub, a.ua) > 0 

El más eficiente dependerá en última instancia de la EXPLAIN plan salida.

JOIN cláusulas son idénticas a las cláusulas de escritura WHERE. La sintaxis JOIN también se conoce como ANSI JOIN porque estaban estandarizadas. No ANSI JOIN parezca:

SELECT * 
    FROM TABLE a, 
     TABLE b 
WHERE INSTR(b.column, a.column) > 0 

yo no me voy a molestar con un ejemplo no ANSI LEFT JOIN. El beneficio de la sintaxis ANSI JOIN es que separa lo que está uniendo las tablas de lo que está sucediendo realmente en la cláusula WHERE.

+0

¿Cuál es la mejor velocidad entre LIKE e INSTR para (nombre de dominio, por ejemplo)? – Meloman

5

Si esto es algo que tendrá que hacer a menudo ... entonces es posible que desee desnormalizar la relación entre las tablas A y B.

Por ejemplo, en el inserto de la tabla B, se podría escribir cero o más entradas a una tabla de junción que mapean B a A en base a un mapeo parcial. Del mismo modo, los cambios en cualquiera de las tablas podrían actualizar esta asociación.

Todo esto depende de con qué frecuencia se modifiquen las tablas A y B. Si son bastante estáticos, entonces recibir un golpe en INSERT es menos doloroso que los golpes repetidos en SELECT.

+2

Esa es una buena solución, pero no es exacto llamarlo desnormalización. –

+2

Bastante justo. Llámalo una mesa de reunión y luego –

1

El uso de criterios condicionales en una unión es definitivamente diferente de la cláusula Where. La cardinalidad entre las tablas puede crear diferencias entre las cláusulas Join y Where.

Por ejemplo, si se utiliza una condición similar en una unión externa, se conservarán todos los registros en la primera tabla enumerada en la combinación.Usar la misma condición en la cláusula Where cambiará implícitamente la unión a una unión interna. El registro generalmente debe estar presente en ambas tablas para lograr la comparación condicional en la cláusula Where.

Generalmente utilizo el estilo dado en una de las respuestas anteriores.

tbl_A as ta 
    LEFT OUTER JOIN tbl_B AS tb 
      ON ta.[Desc] LIKE '%' + tb.[Desc] + '%' 

De esta manera puedo controlar el tipo de unión.

Cuestiones relacionadas