Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

duda con consulta

Estas en el tema de duda con consulta en el foro de Mysql en Foros del Web. Hola de hace días que tengo esta duda y no he podido resolverla se trata de esto: tengo 3 tablas una que tiene el nombre ...
  #1 (permalink)  
Antiguo 24/07/2012, 16:15
 
Fecha de Ingreso: noviembre-2006
Mensajes: 83
Antigüedad: 17 años, 5 meses
Puntos: 0
Pregunta duda con consulta

Hola de hace días que tengo esta duda y no he podido resolverla se trata de esto:

tengo 3 tablas una que tiene el nombre hospitales, otra con tratamientos que se pueden realizar por hospital y la ultima con con la información de estos dos osea que por cada hospital se puede tener muchos tratamientos.

Lo que necesito hacer es que no se repita la información si ya esta agregada he usado este código

http://www.designchemical.com/lab/jq...elect_list.htm

la idea principal es que no se repitan los datos en el select de la izquierda si ya fueron agregados a la derecha cuando se refresca la pagina.

Gracias
  #2 (permalink)  
Antiguo 24/07/2012, 17:05
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

Pues, lo siento pero las consultas deben ser posteadas aquí. Postear un link pone en riesgo a los foristas ante malwareS potenciales que puedan presentarse en los sitios usados.
Resumiendo:
Copia y postea la consulta aquí, y agrega la estructura de las tablas, porque lo que hay en ese link es insuficiente para una buena respuesta.
Posdata: Los refrescos de página no son asunto de MySQL. Sólo resolveremos el tema de la consulta. El resto preguntalo en el foro de Jscript.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 24/07/2012 a las 18:42
  #3 (permalink)  
Antiguo 24/07/2012, 18:41
 
Fecha de Ingreso: noviembre-2006
Mensajes: 83
Antigüedad: 17 años, 5 meses
Puntos: 0
Respuesta: duda con consulta

entiendo, he hecho un dibujo para explicar mejor de todas maneras el problema es la consulta no el jscripts

  #4 (permalink)  
Antiguo 24/07/2012, 19:41
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

Es posible que haya un error de comprensión sobre lo que devuelve una consulta cuando realizas una relación entre tres tablas donde una de ellas es la representación de una relación N:N entre dos entidades.
Cuando generas una consulta tal que relacione esas tablas, los valores de la tabla izquierda (la tabla base de la consulta9, siempre se repetirán una vez por cada coincidencia entre esa tabla y la segunda. Eso es inevitable, porque lo que no se repite es el conjunto completo de valores.
En otras palabras:
Si tenemos las tablas que indicas:
Código MySQL:
Ver original
  1. mysql> DROP TABLE IF EXISTS clinica, prestacion, isapres;
  2. Query OK, 0 rows affected (0.05 sec)
  3.  
  4. mysql> CREATE TABLE IF NOT EXISTS clinica
  5.     ->     (ID_CLINICA INT UNSIGNED PRIMARY KEY,
  6.     ->     VAL_CLINICA VARCHAR(50));
  7. Query OK, 0 rows affected (0.06 sec)
  8.  
  9. mysql> CREATE TABLE IF NOT EXISTS prestacion
  10.     ->     (ID_ISAPRES INT UNSIGNED,
  11.     ->     ID_CLINICA INT UNSIGNED,
  12.     ->     PRIMARY KEY(ID_ISAPRES, ID_CLINICA));
  13. Query OK, 0 rows affected (0.01 sec)
  14.  
  15. mysql> CREATE TABLE IF NOT EXISTS isapres
  16.     ->     (ID_ISAPRES INT UNSIGNED PRIMARY KEY,
  17.     ->     VAL_ISAPRES VARCHAR(50));
  18. Query OK, 0 rows affected (0.05 sec)
  19.  
  20. mysql> INSERT INTO isapres
  21.     -> VALUES
  22.     ->     (1, 'BANMEDICA'),
  23.     ->     (2, 'SINSALUD'),
  24.     ->     (3, 'CORMENA'),
  25.     ->     (4, 'CORMENAL');
  26. Query OK, 4 rows affected (0.00 sec)
  27. Records: 4  Duplicates: 0  Warnings: 0
  28.  
  29. mysql> INSERT INTO clinica
  30.     -> VALUES
  31.     ->     (1, 'LAS LILAS'),
  32.     ->     (2, 'LAS FLORES');
  33. Query OK, 2 rows affected (0.00 sec)
  34. Records: 2  Duplicates: 0  Warnings: 0
  35.  
  36. mysql> INSERT INTO prestacion
  37.     -> VALUES
  38.     ->     (2, 1),
  39.     ->     (3, 1);
  40. Query OK, 2 rows affected (0.00 sec)
  41. Records: 2  Duplicates: 0  Warnings: 0

Podemos hacer la consulta con LEFT JOIN o INNER JOIN.
En el primer caso tendremos:
Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->     I.ID_ISAPRES,
  3.     ->     I.VAL_ISAPRES,
  4.     ->     IFNULL(C.ID_CLINICA, '') ID_CLINICA,
  5.     ->     IFNULL(C.VAL_CLINICA, '') VAL_CLINICA
  6.     -> FROM isapres I
  7.     ->     INNER JOIN
  8.     ->     prestacion P ON I.ID_ISAPRES = P.ID_ISAPRES
  9.     ->     INNER JOIN clinica C ON P.ID_CLINICA = C.ID_CLINICA;
  10. +------------+-------------+------------+-------------+
  11. | ID_ISAPRES | VAL_ISAPRES | ID_CLINICA | VAL_CLINICA |
  12. +------------+-------------+------------+-------------+
  13. |          2 | SINSALUD    | 1          | LAS LILAS   |
  14. |          3 | CORMENA     | 1          | LAS LILAS   |
  15. +------------+-------------+------------+-------------+
  16. 2 rows in set (0.00 sec)
En el segundo caso será:

Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->     I.ID_ISAPRES,
  3.     ->     I.VAL_ISAPRES,
  4.     ->     IFNULL(C.ID_CLINICA, '') ID_CLINICA,
  5.     ->     IFNULL(C.VAL_CLINICA, '') VAL_CLINICA
  6.     -> FROM isapres I
  7.     ->     LEFT JOIN
  8.     ->     prestacion P ON I.ID_ISAPRES = P.ID_ISAPRES
  9.     ->     LEFT JOIN clinica C ON P.ID_CLINICA = C.ID_CLINICA;
  10. +------------+-------------+------------+-------------+
  11. | ID_ISAPRES | VAL_ISAPRES | ID_CLINICA | VAL_CLINICA |
  12. +------------+-------------+------------+-------------+
  13. |          1 | BANMEDICA   |            |             |
  14. |          2 | SINSALUD    | 1          | LAS LILAS   |
  15. |          3 | CORMENA     | 1          | LAS LILAS   |
  16. |          4 | CORMENAL    |            |             |
  17. +------------+-------------+------------+-------------+
  18. 4 rows in set (0.05 sec)

Sobre la base de esto, aclárame qué es lo que realmente quieres representar, y cuáles "repeticiones" son las que mencionas, porque no se termina de entender.

Nota: En tu ejemplo, tienes repetidos los datos de una de las tablas, lo que se considera una inconsistencia gravísima.

Nota 2: La próxima vez usa un programa de diseño asistido para hacer el diagrama. Algo como el MySQL Workbench o el Navicat. Será mucho claro para ver las relaciones y las entidades, y además tendrás una herramienta apropiada para trabajar.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 24/07/2012, 20:21
 
Fecha de Ingreso: noviembre-2006
Mensajes: 83
Antigüedad: 17 años, 5 meses
Puntos: 0
Respuesta: duda con consulta

Nota: En tu ejemplo, tienes repetidos los datos de una de las tablas, lo que se considera una inconsistencia gravísima.

sorry eso fue un error de tipeo solamente

ahora sobre lo que necesito es lo contrario osea en este caso sin salud y cormena son las que tomo con un inner join facilmente lo que necesito es saber las que no están en la tabla prestaciones en este caso es la isapre 01 y la isapre 04
  #6 (permalink)  
Antiguo 24/07/2012, 20:35
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

Cita:
ahora sobre lo que necesito es lo contrario osea en este caso sin salud y cormena son las que tomo con un inner join facilmente lo que necesito es saber las que no están en la tabla prestaciones en este caso es la isapre 01 y la isapre 04
Eso es todavía más sencillo.
Si te fijas con cuidado, verás que la segunda consulta devuelve nulos precisamente donde no hay coincidencias. Son esos nulos los que debes buscar, teniendo en cuenta que si son NULL, la tercera tabla no devolverá ningún dato.
Código MySQL:
Ver original
  1. -> WHERE C.ID_CLINICA IS NULL;
  2. +------------+-------------+------------+-------------+
  3. | ID_ISAPRES | VAL_ISAPRES | ID_CLINICA | VAL_CLINICA |
  4. +------------+-------------+------------+-------------+
  5. |          1 | BANMEDICA   |            |             |
  6. |          4 | CORMENAL    |            |             |
  7. +------------+-------------+------------+-------------+
  8. 2 rows in set (0.16 sec)

O bien:
Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->     I.ID_ISAPRES,
  3.     ->     I.VAL_ISAPRES,
  4.     ->     IFNULL(C.ID_CLINICA, '') ID_CLINICA,
  5.     ->     IFNULL(C.VAL_CLINICA, '') VAL_CLINICA
  6.     -> FROM isapres I
  7.     ->     LEFT JOIN
  8.     ->     prestacion P ON I.ID_ISAPRES = P.ID_ISAPRES
  9.     ->     LEFT JOIN clinica C ON P.ID_CLINICA = C.ID_CLINICA
  10.     -> WHERE P.ID_ISAPRES IS NULL;
  11. +------------+-------------+------------+-------------+
  12. | ID_ISAPRES | VAL_ISAPRES | ID_CLINICA | VAL_CLINICA |
  13. +------------+-------------+------------+-------------+
  14. |          1 | BANMEDICA   |            |             |
  15. |          4 | CORMENAL    |            |             |
  16. +------------+-------------+------------+-------------+
  17. 2 rows in set (0.00 sec)

Como verás, apoyarte en la segunda tabla o en la tercera da el mismo resultado.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 24/07/2012, 21:50
 
Fecha de Ingreso: noviembre-2006
Mensajes: 83
Antigüedad: 17 años, 5 meses
Puntos: 0
Respuesta: duda con consulta

mm esta bueno el ejemplo pero ayudame a entender un poco mas por favor tengo que usar un WHERE final para listar la informacion por clinica osea ese campo no puede ser null pero si hago WHERE de esta manera no sale nada

WHERE P.ID_ISAPRES IS NULL AND P.ID_CLINICA=1
  #8 (permalink)  
Antiguo 24/07/2012, 22:01
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

Es que si una prestación no se ha realizado en una clínica, la clínica jamás saldrá en el listado.
Es como decir que lo que quieres es el listado de clínicas donde jamás se realizó una determinada prestación. Para lograrlo hay que invertir las tablas:
Código MySQL:
Ver original
  1. mysql> SELECT
  2.     ->     C.ID_CLINICA,
  3.     ->     C.VAL_CLINICA,
  4.     ->     IFNULL(I.ID_ISAPRES, '') ID_ISAPRES,
  5.     ->     IFNULL(I.VAL_ISAPRES, '') VAL_ISAPRES
  6.     -> FROM clinica C
  7.     ->     LEFT JOIN
  8.     ->     prestacion P ON P.ID_CLINICA = C.ID_CLINICA
  9.     ->     LEFT JOIN isapres I ON I.ID_ISAPRES = P.ID_ISAPRES
  10.     -> WHERE P.ID_ISAPRES IS NULL;
  11. +------------+-------------+------------+-------------+
  12. | ID_CLINICA | VAL_CLINICA | ID_ISAPRES | VAL_ISAPRES |
  13. +------------+-------------+------------+-------------+
  14. |          2 | LAS FLORES  |            |             |
  15. +------------+-------------+------------+-------------+
  16. 1 row in set (0.01 sec)
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 24/07/2012, 22:11
 
Fecha de Ingreso: noviembre-2006
Mensajes: 83
Antigüedad: 17 años, 5 meses
Puntos: 0
Respuesta: duda con consulta

pero al agregar AND al WHERE para listar una clinica no aparece resultado
  #10 (permalink)  
Antiguo 24/07/2012, 22:24
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

Si no aparece la clínica, es porque al menos hay un registro de esa clínica que corresponde a un registro de prestaciones. Y lo que estás planteando es
Cita:
necesito es saber las que no están en la tabla prestaciones
Lo que puede estar pasando es que no resulte claro qué es lo que quieres buscar:
- Las prestaciones que no se han realizado en ninguna clínica.
- Las Clínicas que no han realizado una determinada prestación.
- Las Clínicas que no han realizado todos los tipos de prestación...

No creas que porque tu lo sepas yo lo estoy entendiendo de la misma forma. A mí no me resulta claro exactamente lo que quieres mostrar.
¿Ves cómo he listado esos tres ejemplos? Bueno, describe lo que debe contener ese reporte de la misma forma.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 24/07/2012, 22:58
 
Fecha de Ingreso: noviembre-2006
Mensajes: 83
Antigüedad: 17 años, 5 meses
Puntos: 0
Respuesta: duda con consulta

disculpa si no he sido lo suficientemente claro voy a tratar de aclarar mas

necesito listar una clinica y mostrar las isapres que no aparecen en las prestaciones todo esto con el fin de no duplicar los datos del select cada vez que se refresca la pagina



esto lo hago por medio de ajax pero cuando refresco la pagina obviamente el select de la izquierda se llena con todos los datos nuevamente con los datos de la tabla isapres y en la derecha quedan los datos de la tabla prestaciones agregados

eso es dime si me entiendes mejor por favor
  #12 (permalink)  
Antiguo 25/07/2012, 04:38
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

Cita:
listar una clinica y mostrar las isapres que no aparecen en las prestaciones
Se entiende... pero para lograr relacionar las clínicas con las prestaciones con las que no están vinculadas, se tiene que recurrir a una consulta súmamente ineficiente: Hay que generar un producto cartesiano, eliminar aquellas con las que si están vinculadas y desartar todas las demás clínicas.
En esencia, es posible, pero en realidad sería mucho más sencillo y eficiente hacer dos consultas.
Dejame un rato, que ahora me voy a trabajar, y te contesto.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #13 (permalink)  
Antiguo 25/07/2012, 06:30
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

(Desde la oficina)
La idea sería que se realice un producto cartesiano, pero que se discrimine todos los pares que no se encuentren ya en la tabla de prestaciones.
Eso devolverá una tabla bastante grande de datos, donde la clínica se repetirá una vez por cada producto que no se encuentre en la tabla, por lo que hay tres formas de encarar la cosa:

1) Si quieres los datos de todas las clínicas y de la prestaciones:
Código MySQL:
Ver original
  1.     C.ID_CLINICA,
  2.     C.VAL_CLINICA,
  3.     I.ID_ISAPRES,
  4.     I.VAL_ISAPRES
  5. FROM clinica C, isapres I
  6.     (I.ID_ISAPRES, C.ID_CLINICA) NOT IN (SELECT ID_ISAPRES, ID_CLINICA FROM prestacion P)
  7. ORDER BY C.ID_CLINICA;

2) Si quieres sólo los de una clínica:
Código MySQL:
Ver original
  1.     C.ID_CLINICA,
  2.     C.VAL_CLINICA,
  3.     I.ID_ISAPRES,
  4.     I.VAL_ISAPRES
  5. FROM clinica C, isapres I
  6.     (I.ID_ISAPRES, C.ID_CLINICA) NOT IN (SELECT ID_ISAPRES, ID_CLINICA FROM prestacion P)
  7.     AND C.ID_CLINICA = valorBuscado
  8. ORDER BY I.VAL_ISAPRES;

3) Si quieres sólo las prestaciones que no se hicieron en esa clínica:
Código MySQL:
Ver original
  1.     DISTINCT
  2.     I.ID_ISAPRES,
  3.     I.VAL_ISAPRES
  4. FROM clinica C, isapres I
  5.     (I.ID_ISAPRES, C.ID_CLINICA) NOT IN (SELECT ID_ISAPRES, ID_CLINICA FROM prestacion P)
  6.     AND C.ID_CLINICA = valorBuscado;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #14 (permalink)  
Antiguo 25/07/2012, 15:56
 
Fecha de Ingreso: noviembre-2006
Mensajes: 83
Antigüedad: 17 años, 5 meses
Puntos: 0
Respuesta: duda con consulta

muchas gracias por tu ayuda es lo que estaba buscando ahora a tomar un tiempo más para entenderla mejor :D

te agradecería un montón si me ayudaras a comprender como funciona la ultima

de verdad muchas gracias
  #15 (permalink)  
Antiguo 25/07/2012, 17:30
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: duda con consulta

Para entender esa consulta hay que comprender un sólo concepto: Producto Cartesiano
Como puedes ver en el link, genera una tabla donde cada valor de una tabla se combina con cada valor de la otra, en una multiplicación de conjuntos. Eso genera todas las combinaciones posibles entre ambas.
Luego viene el IN(). Esta cláusula verifica si un valor dado existe o no dentro de una lista de valores. Esa lista puede ser una lista separada por comas, o bien el resultado de una consulta.
El truco consiste en que debemos buscar un valor de clave que es doble (dos campos), por lo que para que tome el par combinado el valor a comparar debe ser encerrado entre paréntesis, y la subconsulta debe ser sobre los dos mismos campos, de la otra tabla.
El secreto principal es el que los campos en ambos casos deben estar en el mismo orden, o de lo contrario los resultados serán erróneos.
¿Se entiende?
Como la consulta mayor opera sobre un producto cartesiano, devolverá todas las combinatorias que pueden darse, al poner NOT IN, eliminará las que existen y devolverá el resto.
Atención: El producto cartesiano es la peor consulta que existe (un P.C. sobre dos tablas de 10.000 registros devolverían 100 millones, por ejemplo), y se debe usar si y sólo si es absolutamente necesario, como en este caso, y jamás con tablas grandes.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: select, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:56.