Pregunta:
Fecha: 03-09-2015 11:04:24
(En Español)
Introito:
Imaginemos tengo 2 tablas
tabla_a (id_a, n_telefono, nombre)
tabla_b (id_b, n_telefono, msn, fecha)
Ahora bien:
Supongamos que quiero hacer una consulta, donde coincidan en ambas tablas los n_telefono
Las consultas Mysql podrian ser asi:
SELECT *
FROM tabla_a, tabla_b
WHERE tabla_a.n_telefono = tabla_b.n_telefono
ORDER BY fecha DESC
o tambien asi:
SELECT *
FROM tabla_a
INNER JOIN tabla_b
ON tabla_a.n_telefono = tabla_b.n_telefono;
Hasta aqui sencillo, ningun problema.
Ahora vamos a lo mas complicado:
Tengo la tabla_b (id_b, n_telefono, msn, fecha)
Con un campo n_telefonos.
Mediante un Form se ingresan los registros, donde el input del campo n_telefono, es un selector multiple, enviandome registros que pueden tener las siguientes caracteristicas:
Ejemplo:
Campo: n_telefono
INPUT - Select multiple:
Caso a) Registro = 40408080 (CARACTERES)
Caso b) Registro = 40408080, 30305050, 60609090, 10102050 (CADENA DE CARACTERES)
En el Caso a) recibio un solo numeros de telefono,
En el Caso b) recibio varios numeros de telefono, separados por una "," (COMA) como separador
Si yo hago las consultas que expuse, solo obtengo los registros, donde coinciden los n_telefono siempre y cuando en el campo de la tabla_b campo n_numero el registro sea de caracteres, si es tadena de caracteres no los lee.
En mi caso debo obtener todos los msn que se enviaron mediante una tabla a todos los n_telefono
Pregunta
¿Como deberia hacer la consulta para obtener el resultado pretendido?
A mi se me ocurre un foreach, pero no logro encontar la solucion
Desde ya muchas gracias a los que puedan colaborar
Votos: 0 - Respuestas: 16 - Vistas: 17 Compartir en: Google Facebook Twitter LinkedIn Link
Consulta MySQL - Relacionar tablas por campos desnormalizados[Resuelta]
Buanas tardes a todos:Introito:
Imaginemos tengo 2 tablas
tabla_a (id_a, n_telefono, nombre)
tabla_b (id_b, n_telefono, msn, fecha)
Ahora bien:
Supongamos que quiero hacer una consulta, donde coincidan en ambas tablas los n_telefono
Las consultas Mysql podrian ser asi:
SELECT *
FROM tabla_a, tabla_b
WHERE tabla_a.n_telefono = tabla_b.n_telefono
ORDER BY fecha DESC
o tambien asi:
SELECT *
FROM tabla_a
INNER JOIN tabla_b
ON tabla_a.n_telefono = tabla_b.n_telefono;
Hasta aqui sencillo, ningun problema.
Ahora vamos a lo mas complicado:
Tengo la tabla_b (id_b, n_telefono, msn, fecha)
Con un campo n_telefonos.
Mediante un Form se ingresan los registros, donde el input del campo n_telefono, es un selector multiple, enviandome registros que pueden tener las siguientes caracteristicas:
Ejemplo:
Campo: n_telefono
INPUT - Select multiple:
Caso a) Registro = 40408080 (CARACTERES)
Caso b) Registro = 40408080, 30305050, 60609090, 10102050 (CADENA DE CARACTERES)
En el Caso a) recibio un solo numeros de telefono,
En el Caso b) recibio varios numeros de telefono, separados por una "," (COMA) como separador
Si yo hago las consultas que expuse, solo obtengo los registros, donde coinciden los n_telefono siempre y cuando en el campo de la tabla_b campo n_numero el registro sea de caracteres, si es tadena de caracteres no los lee.
En mi caso debo obtener todos los msn que se enviaron mediante una tabla a todos los n_telefono
Pregunta
¿Como deberia hacer la consulta para obtener el resultado pretendido?
A mi se me ocurre un foreach, pero no logro encontar la solucion
Desde ya muchas gracias a los que puedan colaborar
Votos: 0 - Respuestas: 16 - Vistas: 17 Compartir en: Google Facebook Twitter LinkedIn Link
Respuestas:
-
Fecha: 04-09-2015 05:37:25 Hola Daniel, según entiendo estas necesitando filtrar el resultado del INNER JOIN con la lista de telefonos que te llegan por parametro, no?
Si es así, simplemente puede usar algo como un WHERE con la instrucción IN.
Por ejemplo:
SELECT * FROM tabla_a INNER JOIN tabla_b ON tabla_a.n_telefono = tabla_b.n_telefono WHERE tabla_b.n_telefono IN (40408080, 30305050, 60609090, 10102050);
Espero haber comprendido bien tu problema, cualquier cosa me dices.
Saludos,
Fernando Votos: 0 - Link respuesta -
Fecha: 04-09-2015 06:08:58 Fernando:
Ante todo, gracias por tu respuesta.
SELECT * FROM tabla_a INNER JOIN tabla_b ON tabla_a.n_telefono = tabla_b.n_telefono WHERE tabla_b.n_telefono IN (40408080, 30305050, 60609090, 10102050);
En el ejemplo que me das, es para el caso en que yo quiera consultar esos números determinados.
Dando un resultado similar al que tengo.
Cuando el usuario envían un msn los hacen por medio de un SELECTOR MULTIPLE, por lo tanto puede enviar un mensaje a uno o varios números de teléfono, alojándose ese dato en la tabla: tabla_b - Campo: n_telefono, a veces puede contener una cadena de caracteres, delimitado por comas (,).
El campo puede recibir un registro (con un numero de teléfono) o también, puede recibir un registro (que contenga varios números de teléfono), como esta delimitado, puede tomar un formato de array().
Se que tengo que comparar:
tabla_a.n_telefono = tabla_b.n_telefono
El tema es que:
tabla_a.n_telefono tiene el teléfono de cada cliente
tabla_b.n_telefono tiene los números de teléfono a los que han llamado, solo que puede haber un registro con un solo numero (Alli la consulta funciona bien) o puede tener como registro varios números de teléfono (40408080, 30305050, 60609090, 10102050, etc).
¿Espero que se comprenda mi pregunta?
Nuevamente gracias
Daniel Votos: 0 - Link respuesta -
Fecha: 04-09-2015 07:33:09 Hola Daniel:
Creo que lo que deberíamos hacer es recorrer el campo como array, en tu caso, el segundo elemento comparativo (tabla_b.n_telefono).
Desde mi inexperiencia (nunca me enfrenté a un caso similar) la variedad en el tratamiento de arrays la tienes, como página de base, en http://php.net/manual/es/book.array.php
El camino posiblemente no sea el mejor pero sería meter la consulta FROM tabla_a INNER JOIN tabla_b dentro del for correspondiente. Votos: 0 - Link respuesta -
Fecha: 04-09-2015 08:24:20 Ahora creo entender un poco mejor, fijate con esta query, aquí aplique la función de MySQL FIND_IN_SET
SELECT * FROM tabla_a INNER JOIN tabla_b ON (FIND_IN_SET(tabla_a.n_telefono,tabla_b.n_telefono)>0);
Saludos! Votos: 0 - Link respuesta -
Fecha: 04-09-2015 10:41:03 Fernando, Artzain
Gracias nuevamente por su colaboracion:
Fernando, con la consulta que me envias, obtengo todos los registros por cada msn que se envio.
Lo que sigo sin obtener es:
Por cada n_telefono que figure en la cadena de caracteres el nombre de cada uno
Comento:
Probe con un foreach
[foreach(explode(',', $n_telefono) as $numero
Donde psteriormente por medio de otra consulta $numero sea una variable y tampco resulto
Daniel Votos: 0 - Link respuesta -
Fecha: 04-09-2015 13:07:13 La query que te pase te puede devolver el nombre de todos los teléfonos relacionados sin repetidos usando un GROUP BY
SELECT tabla_a.nombre FROM tabla_a INNER JOIN tabla_b ON (FIND_IN_SET(tabla_a.n_telefono,tabla_b.n_telefono)>0) GROUP BY tabla_a.id_a;
Votos: 0 - Link respuesta -
Fecha: 04-09-2015 14:21:23 Fernando:
Nuevamente gracias por tu respuesta
Aca veras graficamente lo que pretendo
tabla_a Campos id_a | n_telefono | nombre 1 11111111 Pepe 2 22222222 Tito 3 33333333 Tato tabla_b Campos id_b | fecha | msn | n_telefono | 1 2015-01-01 Hola 11111111 2 2015-03-04 Paz 11111111, 2222222, 33333333 3 2015-04-01 SOS 3333333 ***Recuerdo que el Campo n_telefono, puede recibir: a) Un conjunto de caracteres Ejemplo: 11111111 b) Una cadena de caracteres Ejemplo: 11111111, 2222222, 33333333 Resultado PRETENDIDO fecha | msn | n_telefono | Nombre 2015-01-01 Hola 11111111 Pepe 2015-03-04 Paz 11111111 Pepe 2015-03-04 Paz 22222222 Tito 2015-03-04 Paz 33333333 Tato 2015-04-01 SOS 33333333 Tato Resultado NO DESEADO fecha | msn | n_telefono | Nombre 2015-01-01 Hola 11111111 Pepe 2015-03-04 Paz 11111111, 22222222, 3333333 2015-04-01 SOS 33333333 Tato
Daniel Votos: 0 - Link respuesta -
Fecha: 05-09-2015 04:22:59 Creación de tablas y modelo de datos para intentar obtener el resultado correcto (100% ejecutable en MySQL Community Edition):
Creo las tablas y las cargo con los datos dummy:
CREATE TABLE `tabla_a` ( `id_a` int(10) unsigned NOT NULL AUTO_INCREMENT, `n_telefono` varchar(250) DEFAULT NULL, `nombre` varchar(250) DEFAULT NULL, PRIMARY KEY (`id_a`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO tabla_a VALUES (1,'11111111', 'Pepe'), (2,'22222222', 'Tito'), (3,'33333333', 'Tato'); CREATE TABLE `tabla_b` ( `id_b` int(10) unsigned NOT NULL AUTO_INCREMENT, `fecha` date DEFAULT NULL, `msn` varchar(250) DEFAULT NULL, `n_telefono` varchar(250) DEFAULT NULL, PRIMARY KEY (`id_b`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO tabla_b VALUES (1, '2015-01-01', 'Hola', '11111111'), (2, '2015-03-04', 'Paz', '11111111, 22222222, 33333333'), (3, '2015-04-01', 'SOS', '33333333');
---------------
Si quieres obtener el resultado no deseado, aquí las query's
Ajustando los campos SELECT
SELECT tabla_b.fecha, tabla_b.msn, tabla_b.n_telefono, tabla_a.nombre FROM tabla_a INNER JOIN tabla_b ON (FIND_IN_SET(tabla_a.n_telefono,tabla_b.n_telefono)>0);
Si perfecciono el SELECT con un CASE para devolver nombre vacío cuando hay más de un telefono (aquí el resultado es mas exacto)
SELECT tabla_b.fecha, tabla_b.msn, tabla_b.n_telefono, CASE WHEN locate(',',tabla_b.n_telefono)>0 THEN '' ELSE tabla_a.nombre END FROM tabla_a INNER JOIN tabla_b ON (FIND_IN_SET(tabla_a.n_telefono,tabla_b.n_telefono)>0);
Resultado no deseado:
2015-01-01 Hola 11111111 Pepe 2015-03-04 Paz 11111111, 22222222, 33333333 2015-04-01 SOS 33333333 Tato
---------------
Lo anterior lo deje porque tal vez aporta alguna idea nueva, si encuentro la solución correcta la posteo.
Saludos, Votos: 0 - Link respuesta -
Fecha: 05-09-2015 04:48:44 Fernando:
Gracias nuevamente
Pero como te dije en mi POST anterior el:
RESULTADO DESEADO fecha | msn | n_telefono | Nombre 2015-01-01 Hola 11111111 Pepe 2015-03-04 Paz 11111111 Pepe 2015-03-04 Paz 22222222 Tito 2015-03-04 Paz 33333333 Tato 2015-04-01 SOS 33333333 Tato
Daniel Votos: 1 - Link respuesta -
Fecha: 05-09-2015 05:56:34 Daniel, disculpa la confusión, edite mi respuesta anterior para que por lo menos aporte algo y no confunda, si encuentro la solución correcta la posteo.
Saludos, Votos: 0 - Link respuesta -
Fecha: 05-09-2015 10:00:37 Fernando:
Estoy tratando de buscar por PHP la solucion, encare por este lado:
<?php $db = mysqli_connect("localhost","root","","mi_bd"); $rs = mysqli_query($db,"SELECT * FROM tabla_b"); while ($row = mysqli_fetch_assoc($rs)) { $array = array( $id_b=$row['id_b'], $fecha=$row['fecha'], $msn=$row['msn'], $n_telefono=$row['n_telefono'] ); $telefono = explode(",", $n_telefono); print_r($telefono); } ?>
OBTENGO ESTE RESULTADO:
Array ( [0] => 11111111 ) Array ( [0] => 11111111 [1] => 2222222 [2] => 33333333 ) Array ( [0] => 33333333 )
Lo que implica que estoy separando a la cadena de caracteres, lo que me permitiria hacer una nueva consulta en donde utilizando las 2 tablas comparando
WHERE tabla_a.n_telefono = $array // o algo parecido
Hasta aqui llegue, aun no lo he resuelto.
Un saludo
Daniel Votos: 0 - Link respuesta -
Fecha: 06-09-2015 03:33:06 Buenos días Daniel, finalmente llegue a la solución por medio de un stored procedure al que llamé "sp_mensajes", aquí el código 100% funcional.
Creación del stored procedure:
DELIMITER $$ DROP PROCEDURE IF EXISTS sp_mensajes $$ CREATE PROCEDURE sp_mensajes() BEGIN DECLARE separador VARCHAR(255) DEFAULT ','; DECLARE var_id_b INT DEFAULT 0; DECLARE var_fecha TEXT; DECLARE var_msn TEXT; DECLARE var_n_telefono TEXT; DECLARE ocurrencias INT DEFAULT 0; DECLARE i INT DEFAULT 0; DECLARE n_telefono_dividido INT; DECLARE done INT DEFAULT 0; DECLARE cursor_tabla_b CURSOR FOR SELECT id_b, fecha, msn, n_telefono FROM tabla_b WHERE tabla_b.n_telefono != ''; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; DROP TEMPORARY TABLE IF EXISTS explode_tabla_b; CREATE TEMPORARY TABLE explode_tabla_b( `id_b` INT NOT NULL, `fecha` date DEFAULT NULL, `msn` varchar(250) DEFAULT NULL, `n_telefono` varchar(250) NOT NULL ) ENGINE=Memory DEFAULT CHARSET=utf8; OPEN cursor_tabla_b; read_loop: LOOP FETCH cursor_tabla_b INTO var_id_b,var_fecha,var_msn,var_n_telefono; IF done THEN LEAVE read_loop; END IF; SET ocurrencias = (SELECT LENGTH(var_n_telefono) - LENGTH(REPLACE(var_n_telefono, separador, '')) + 1); SET i=1; WHILE i <= ocurrencias DO SET n_telefono_dividido = (SELECT REPLACE(SUBSTRING(SUBSTRING_INDEX(var_n_telefono, separador, i), LENGTH(SUBSTRING_INDEX(var_n_telefono, separador, i - 1)) + 1), ',', '')); INSERT INTO explode_tabla_b VALUES (var_id_b,var_fecha,var_msn,n_telefono_dividido); SET i = i + 1; END WHILE; END LOOP; SELECT explode_tabla_b.fecha, explode_tabla_b.msn, explode_tabla_b.n_telefono, tabla_a.nombre FROM explode_tabla_b INNER JOIN tabla_a ON(tabla_a.n_telefono = explode_tabla_b.n_telefono); DROP TEMPORARY TABLE IF EXISTS explode_tabla_b; CLOSE cursor_tabla_b; END; $$ DELIMITER ;
Ejecución del stored procedure:
CALL sp_mensajes();
A modo de resumen, el stored procedure hacer un explode de la tabla_b y persiste el resultado en memoria (de forma temporal), finalmente hace el query (select, inner join, etc etc) y devuelve el resultado esperado.
Espero que mi respuesta te sea de ayuda.
Saludos,
Fernando Votos: 3 - Link respuesta -
Fecha: 07-09-2015 04:56:07 Fernando
Muy agradecido por tu ayuda ...
Pequeño inconveniente (Como no entiendo bien tu script ("por falta de conocimientos") no se como aplicarlo dentro del php)
Gracias nuevamente
Daniel Votos: 0 - Link respuesta -
Fecha: 07-09-2015 05:29:44 Hola Daniel, lo que tienes que hacer es:
1) Adaptar el stored procedure a tu base de datos (nombre de las tablas, cantidad y nombre de las columnas, nombre del stored procedure)
2) Crear el strore procedure en la base de datos (o sea, ejecutar el CREATE PROCEDURE...)
3) Ejecutar el stored procedure desde PHP, el mismo te devolverá la tabla "resultado deseado"
4) Finalmente usar los datos devueltos por el stored procedure... :)
Para ejecutar el stored procedure desde PHP (con MySQLi) puedes hacer algo como:
<?php //conectar a la base de datos $connection = mysqli_connect("hostname", "user", "password", "db", "port"); //ejecutar el stored procedure $result = mysqli_query($connection, "CALL sp_mensajes") or die("Query fail: " . mysqli_error()); //iterar el result set while ($row = mysqli_fetch_array($result)){ echo $row['fecha'] . ' - ' . $row['msn']. ' - ' . $row['n_telefono']. ' - ' . $row['nombre'] . '<br/>'; } ?>
Saludos,
Fernando Votos: 1 - Link respuesta -
Fecha: 09-09-2015 12:32:05 Fernando:
He aprendido en este breve tiempo que si uno pretende programar, no se puede rendir ante nada ...
De hecho me resiste a que no existiera una posibilidad PHP para este tema.
Tanto darme la cabeza contra las paredes, lo logre.
La solucion estaba como siempre detras de un par de lineas de codigo, la cual expongo mas abajo, para quien la pueda necesitar:
Desde ya agradezco infinitamente vuestra colaboracion y de ser nesesario contar con ustedes en a proxima.
<?php /** * Creo Conexion */ $db = mysqli_connect("localhost","root","","afip"); /** * Habo una consulta a la tabla_b */ $rs = mysqli_query($db,"SELECT * FROM tabla_b"); while ($row=mysqli_fetch_array($rs)) { //Obtengo los numeros de telefono independientemente si estan registrados de auno o en un array $n_telefono = $row['n_telefono']; /** * Creo una variable * @var [vector] */ $vector = $n_telefono; /** * Creo una nueva variable en donde contenga todos los numeros de telefono uno por uno * @var [separar] */ $separar = explode(",", $vector); /** * Hago un foreach donde a cada numero de telefono que encuentre, le asigne un valor */ foreach($separar as $valor) { /** * Creo una nueva consulta, pero esta vez entre las 2 tablas (Tabla_a y tabla_b), donde $valor tiene el registro de cada telefono * @var [valor] */ $xx = mysqli_query($db,"SELECT tabla_a.n_telefono, tabla_a.id_a, tabla_b.* FROM tabla_a, tabla_b WHERE tabla_a.n_telefono = $valor"); { $id_b=$row['id_b']; $fecha=$row['fecha']; $msn=$row['msn']; $n_telefono=$row['n_telefono']; echo $id_b ." ". $fecha ." ". $msn ." ". $valor ."<br />"; } } } ?>
Un saludo
Daniel
PD.: Doy la pregunta por RESUELTA Votos: 0 - Link respuesta -
Fecha: 26-12-2018 06:51:40 vaya que buen POST justo estaba buscando algo similar el nivel de la consulta del Sr. fernando es buenísimo. mi pregunta para el Sr. fernando es si ese tipo de consultas es necesaria por seguridad o también se puede trabajar como lo hizo antuan? saludos Votos: 0 - Link respuesta
Para participar activamente de la comunidad primero debes autenticarte, ingresa al sistema.Iniciar Sesión
