Importante duda sobre Consulta SQL AVANZADA

<< < (6/6)

SnakeDrak:
Hola,

Perdona pero creo que no es forma correcta la tuya de responer, ya no pienso ayudar más para que me respondan así, si no sabes hacerlo aprende un poco más de SQL a y te recomiendo que te expreses un poco mejor porque ni tú tienes clara la idea de lo que quieres hacer y si la tienes clara no te expresas/escribes correctamente y algunas cosas no se comprenden.

Eso que dices se puede hacer sin problemas, comparar strings con otras strings y ver el % de comparación, tal vez no en 1 sola consulta, pero en 2 consultas podrías hacerlo.

Por supuesto si te intentan ayudar y respondes así pues.. no creo que te ayuden.

Saludos y suerte.

Skeletron:
Amigo, amigo.. no es apra que te enojes...
Me he redactado todo de nuevo y aqui te lo digo:

Introduccion:
Imaginate que tengo la carpeta: C:/ARCHIVOS y en ella hay 50.000 archivos .txt con MUCHO texto tentro
Desde mi web, (PHP) ingresando otro .txt en un formulario, analizaré si hay un archivo "parecido" al ingresado en mi carpeta C:/ARCHIVOS..
El archivo ingresado, se considera "parecido" si: Es totalmente igual, o hasta en un 70% (ésto es lo que produce el problema)

Dato:
El algoritmo de INDEXADO a la base de datos de los archivo de la carpeta, consiste en tomar 10 muestras de 5 "caracteres" de los archivos de C:/ARCHIVOS y guardarlos consecutivamente como 1 sola gran palabra...
O sea: Con un motor, voy a entrar a cada uno de los archivos y voy a tomar ese muestreo y guardarlo en la base de datos a esa gran palabra que me quedó..
La palabra será de 50 caracteres, proque son 10 muestras de 5 Caracteres..


Web:
Desde la web se ingresa X archivo y se le toma el mismo muestreo...


Opciones:
En la base de datos puedo guardar las muestras de varias formas.. por ejemplo con separadores o sin..
Con separadores: 12345;34567;98654;98764 (y así hasta llegar a las 10 muestras)
O sin separadores: 1234567898765432 (y así hasta llegar a las 10 muestras)


Lo que tengo que hacer:
Con la muestra que tengo del archivo ingresado, tengo que COMPRAR los tramos...
O sea.. agarro los primeros 5 caracteres de la muestra del arcchivo ingresado, y los comparo con los 5 primeros caracteres de la 1º entrada de la base de datos.. en caso de ser TOTALMENTE IGUALES, "suma 1 punto", despues compara los otros 5.. y así... al finalizar el escanero de la primer entrada de la base de datos, me va a decir: "Tenemos 8 tramos iguales", por lo tanto, este archivo supera el 70% establecido de "comparacion", y se considera que el archivo ingresado y la 1º entrada de la base de datos son IGUALES o PARECIDOS.. y por lo tanto, tengo que "devolver" esa entrada con MYSQL..
Despues sigue comparando toda la base de datos y me tiene que devolver normalmente (como siempre lo ahce) el array con las entradas que son "aceptadas" por éste algoritmo...

La pregunta:
¿Como hago eso? :)

Es como que, necesito una CONSULTA SUPER LOGICA...
Tengo 3 opciones:
*Que realmente exista una manera de darle esa logica en la entrada SQL y me quedo feliz..
*Que no exista esa manera de darle logica a SQL y por lo tanto tengo que "recuperar" todas las lineas de la base de datos y compararlas con un algorirmo normal de PHP
*Ponerme a hacer una base de datos que soporte ese sistema de LOGICA y llenarme muy de guita...

^Tifa^:
Hola.

Aunque no te he comprendido 100% tu solicitud (Asumo que igual que el resto juas  :xD )
quiero intentar ayudar  :rolleyes:

Tu peticion si puede realizarse enteramente dentro de MySQL sin problema alguno, pero ojo con esto porque tus peticiones requeriran mucho consumo de RAM dependiento el tamanio que utilizaras para ir comparando valor por valor (Tu entiendes).

Se me ha ocurrido lo siguiente, Tengo 2 tablas :

Código
 
mysql> SELECT * FROM original;
+--------+---------------+
| codigo | nombres       |
+--------+---------------+
|      1 | Luis Castro   |
|      1 | Pedro Sanchez |
|      1 | Maria Lopez   |
|      1 | Juan Veinte   |
|      1 | Pepe Carlos   |
+--------+---------------+
5 ROWS IN SET (0,00 sec)
 
mysql> SELECT * FROM archivo;
+---------------+--------+
| palabra       | codigo |
+---------------+--------+
| Pedro Sanchez |      1 |
| Marcia Mama   |      1 |
| Juan Veinte   |      1 |
| Pepe Carlos   |      1 |
+---------------+--------+
4 ROWS IN SET (0,00 sec)
 

Con los datos ahi mostrados. La tabla original es una tabla guardada en motor MyIsam y la tabla archivo es una tabla guardada en motor Memory... la razon que elegi Memory para la segunda es sencillamente que la segunda tabla sera la encargada de alojar los datos que se encuentren en un 'archivo.txt' no quiero registros definitivos, sino temporales y alojados unicamente en la memoria como si fuesen datos dinamicos  ::) por ende la tabla archivo esta en motor Memory. Los datos a la tabla archivo los cargue con el tipico :

LOAD DATA LOCAL INFILE 'ruta/archivo' INTO archivo;

prosigo... tenemos las 2 tablas anteriores, ahora yo quiero guardar en alguna parte dentro de la DB los valores en modo real que vayan insertandose en la tabla archivo y concuerden con la tabla original, entonces hago una vista ::

Código
 
mysql> CREATE VIEW Ceros AS SELECT strcmp(palabra, nombres) AS total FROM original INNER JOIN archivo HAVING(total) = 0;
Query OK, 0 ROWS affected (0,00 sec)
 
 

la funcion STRCMP funciona igual que en lenguajes C por ende no creo que deba explicarla mucho, pero si te sirve cuando 2 campos comparados son identicos dicha funcion devuelve valor cero, y como en este caso a mi solo me interesan los valores identicos agrego el predicado having igualandolo a cero, asi solo recogos todos los datos identicos en la comparacion  ;)  para gastar menos memoria a la hora de devolver lol...

Ahora viene la mejor parte del asunto :) cree un procedimiento almacenado, para buscar tu objetivo final (Que hayan mas de 70% de registros similares entre ambas tablas)

Código
 
mysql> delimiter $
mysql> CREATE PROCEDURE proceso(OUT palabra CHAR(15), OUT resultado INT)
   -> BEGIN
   -> DECLARE valor_original INTEGER;
   -> DECLARE valor_similar INTEGER;
   -> SELECT COUNT(total) INTO valor_similar FROM Ceros;
   -> SELECT COUNT(*) INTO valor_original FROM original;
   -> SELECT substr((valor_similar/valor_original)%100, 3, 2) INTO resultado;
   -> IF ( resultado > 70 ) THEN
   -> SELECT concat('Hay un 71% o mayor de similares');
   -> ELSE
   -> SELECT concat('Hay un menor de 70% de similares');
   -> END IF;
   -> END;
   -> $
Query OK, 0 ROWS affected (0,00 sec)
 
delimiter> ;
 
 

Perfecto... ahora el procedimiento lo que hace es siempre recoger los valores totales iguales en la vista Cero (Que al ser una vista siempre estara actualizada en tiempo real a cualquier proceso DDL o DML que se apliquen en ambas tablas  ;) ) y basados en dicho resultados, dividido entre el total de todos los registros que componen la tabla original y sacando un porciento, tendremos un resultado :) en este caso solo tenemos 5 valores identicos a la tabla original que contiene 8 registros por lo que si llamamos al procedimiento proceso tendremos :

Código
 
mysql> CALL proceso(@todo, @todito);
+--------------------------------------------+
| concat('Hay un menor de 70% de similares') |
+--------------------------------------------+
| Hay un menor de 70% de similares           |
+--------------------------------------------+
1 ROW IN SET (0,00 sec)
 
Query OK, 0 ROWS affected (0,00 sec)
 
 
 

Pero si le agregamos mas registros similares a ambas tablas, y luego volvemos a llamar al procedimiento tendriamos ::

Código
 
mysql> CALL proceso(@todo, @todito);
+-------------------------------------------+
| concat('Hay un 71% o mayor de similares') |
+-------------------------------------------+
| Hay un 71% o mayor de similares           |
+-------------------------------------------+
1 ROW IN SET (0,01 sec)
 
Query OK, 0 ROWS affected (0,01 sec)
 
mysql> SELECT COUNT(total) FROM Ceros;
+--------------+
| COUNT(total) |
+--------------+
|            8 |
+--------------+
1 ROW IN SET (0,00 sec)
 
mysql> SELECT COUNT(*) FROM original;
+----------+
| COUNT(*) |
+----------+
|       11 |
+----------+
1 ROW IN SET (0,01 sec)
 
 
 

Vas captando mas o menos lo que intento decir  :silbar:

No se si te sirva... espero que si, recuerda que la tabla archivo al estar en motor memory si reinicias, o apagas la DB todos los datos seran eliminados (ya que solo se alojan temporalmente en la memoria ram, asi sacas mas provecho del espacio de ram y accesa mas rapido a los registros).... pero yo te recomendaria que crees un evento CREATE EVENT dentro de MySQL que cada cierto tiempo haga un TRUNCATE a la tabla archivo o cada vez que vayas a LOAD DATA LOCAL INFILE un archivo nuevo le pases un TRUNCATE primero, seguido de un FLUSH TABLES para que limpies la Cache en caso de que uses Cache (Que no te la recomendaria ya que darias mucho uso constante de TRUNCATE) en caso que no uses Cache, pasa cada cierto tiempo un RESET ayuda para desfragmentar...

Intenta si vas a guardar solo caracteres separados de menor de 255 que sean char, ya que longtext o blob o text o similar... la verdad, consume mucho espacio innecesario de memoria y si no vas a dar uso de datos binarios no vale la pena.

Un saludo :)

Skeletron:
Wow..
Muchas Gracias..
Me diste a entender principalmente que me tengo que leer un BUEN tutorial de MySQL :)

Muchas gracias.. ya volveré al psot a analizar bin todo eso cuando conozca mas de MySQL

Navegación

[0] Índice de Mensajes

[*] Página Anterior