mysql-apicultur

A veces uno necesita comparar dos líneas de la misma tabla y se atasca pensando en como hacerlo usando sólo una instancia de la tabla. La solución es muy simple, pero a menudo se nos olvida así que hago esta pequeña entrada a modo de recuerdo.

En una entrada anterior hablábamos de dividir una campo de texto en las palabras que lo contienen. Ahora tenemos una tabla con palabras y queremos encontrar textos en las que aparecen dos de estas palabras. En nuestro caso particular intentamos buscar las apariciones de “Estados Unidos” en el texto.

La solución es sencilla, consiste en usar dos llamadas a la misma tabla con dos alias diferentes, y después identificar de cuál de los campos estamos hablando. Usamos una instrucción “SELECT” con este formato:

SELECT * FROM Palabra p1, Palabra p2
WHERE p1.palabra = ‘Estados’ AND p2.palabra = ‘Unidos’ AND p1.idtexto = p2.idtexto;

Ya veis que una vez entendido el concepto, necesito un alias de cada tabla para cada línea diferente que quiera consultar, y necesito una manera de “pegar” ambas filas. Por motivos de rendimiento, y en la idea de que pensemos en ello cuando hagamos este tipo de consultas, sería mucho más eficiente cambiar el orden de la segunda y tercera consultas, así buscaremos sólo la existencia de nuestra segunda palabra en el texto en el que ya hemos encontrado la primera. Seguro que nuestro bolsillo, el administrador de base de datos o nuestro viejo ordenador nos lo agradecerán. El resultado sería este:

SELECT * FROM Palabra p1, Palabra p2
WHERE p1.palabra = ‘Estados’ AND p1.idtexto = p2.idtexto AND p2.palabra = ‘Unidos’;

Por último, y por poner una pequeña guinda, si queréis mostrar el campo texto que estará en otra tabla, debéis hacer la siguiente modificación en el código:

SELECT * FROM Palabra p1, Palabra p2, textos t
WHERE p1.palabra = ‘Estados’ AND p1.idtexto = p2.idtexto AND p2.palabra = ‘Unidos’ AND p1.idtexto = t.id;

Como el valor de idtexto en ambas tablas es el mismo, podemos usar cualquiera de los dos. Sentíos libres de usar SELECT, no modifica los datos, lo único, tened cuidado con las megaconsultas… en ese sentido es interesante para las primeras pruebas usar la coletilla final LIMIT 100, o 10 o 1000 para no reventar el sistema mientras ajustamos la búsqueda a lo que queramos !Y esto es todo!

Aprovecho para copiar el formato de la instrucción SELECT del manual de SQL:

SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr, ...
[INTO OUTFILE 'file_name' export_options
| INTO DUMPFILE 'file_name']
[FROM table_references
[WHERE where_definition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_definition]
[ORDER BY {col_name | expr | position}
[ASC | DESC] , ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[FOR UPDATE | LOCK IN SHARE MODE]]
Share →