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

Como enlazar multiples tablas. Optimizar consulta

Estas en el tema de Como enlazar multiples tablas. Optimizar consulta en el foro de Mysql en Foros del Web. Es decir, se que hay diferentes formas, pero me encuentro conque tengo que enlazar muchas tablas y es un auténtico caos. Para simplificarme la vida ...
  #1 (permalink)  
Antiguo 08/11/2012, 10:51
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Como enlazar multiples tablas. Optimizar consulta

Es decir, se que hay diferentes formas, pero me encuentro conque tengo que enlazar muchas tablas y es un auténtico caos. Para simplificarme la vida lo he intentado hacer a traves de Access y un driver ODBC aver si así, pero es una consulta muy compleja (o puede que mal hecha) y no ejecutando la consulta se queda la vida eterna intentando realizarla hasta que me canso y tengo que colgarlo.

Esta es la consulta, tampoco creo que sea para tanto, lo único malo serían tantos enlaces. Hay un par de tablas que no se usan porque aun me quedan algunos datos por poner (con sumas de precios para mas inri) pero es que ya si no saco ni esto.

Se que se pueden hacer las relaciones de varias formas. Yo suelo usar esta, aunque se alguna más:
· WHERE tabla1 = tabla2 USING(clave)

Me suena que hay alguna forma de enlazar multiples tablas que usen la misma clave pero no estoy seguro de como es. Aquí la consulta que me crea el access automáticamente tras decirle que campos quiero consultar. La base de datos es un caos no la diseñé yo y está fatal hecha, así que tampoco ayuda.

Código MySQL:
Ver original
  1. SELECT clientes.clacli AS CÓDIGO, articulo.nombre AS NOMBRE, clientes.direccion AS DIRECCIÓN, clientes.localidad AS LOCALIDAD, clientes.telefono AS TELÉFONO, clientes.contacto AS CONTACTO, clientes.provincia AS PROVINCIA, tarifa.nombre AS TARIFA
  2. FROM articulo, catart, factural, tarifa, (factura INNER JOIN clientes ON factura.clacli=clientes.clacli) INNER JOIN tiposcli ON clientes.clatip=tiposcli.clatip
  3. WHERE articulo.clacat=21 And clientes.clatip=2;
Como veis los enlaces entre tablas son excesivamente complejos, me imagino que por eso se muere.

He intentado hacerlo a mano pero no logro seguir un orden lógico.
Si enlazo articulo con catart (categoria articulo) luego esta categoria con cual la voy a enlazar? no se si me explico. Hay que seguir un orden no?

Este es el meollo:
TABLA -> Su clave y las que llama

articulo
claart(pk)
clacat (fk de categoria articulo)


factura
clafac(pk)


factural
clafacl (pk)
clafact (fk de factura)

tarifa
clatar (pk)

clientes
clacli (pk)
clatar (fk)
clatip (fk)

tiposcli
clatip (pk)

catart
clacat (pk)

Como veis los nombres de las tablas e ids tampoco ayudan mucho. Un auténtico lío. No pido que me hagais la relación sino la sintaxis para poder enlazar varias tablas porque no encuentro un orden en el que hacerlo.

Extra: También si alguno de vosotros sabe me gustaría saber si en una subconsulta puedo hacer referencia a alguna de las claves de la consulta normal. Algo así:
SELECT campos, (SELECT otras_cosas FROM tablas WHERE id_de_la_otra_consulta) FROM tablas

Es decir que para cada id de la consulta principal me busque en la subconsulta.

Última edición por alyciashape; 08/11/2012 a las 11:15 Razón: Mal etiquetado de codigo SQL
  #2 (permalink)  
Antiguo 08/11/2012, 11:16
Avatar de Heimish2000  
Fecha de Ingreso: enero-2011
Ubicación: Madrid
Mensajes: 844
Antigüedad: 13 años, 2 meses
Puntos: 89
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Usa JOINS para unir todas las tablas y en el where pon la condición más restrictiva primero.
  #3 (permalink)  
Antiguo 09/11/2012, 04:40
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Gracias al final lo he conseguido separando las consultas en 2. Como puedo unir ambas?
Pero uniéndolas de forma que la tabla a busque su correspondiente en la tabla B.

Es decir, tengo estas 2 consultas:
Código MySQL:
Ver original
  1. SELECT c.clacli, SUM((fl.precio-((fl.precio*fl.dto)/100))*fl.cantidad) AS 'TOTAL 2012'
  2. FROM clientes c, factura f, factural fl, articulo a
  3. WHERE c.clacli=f.clacli AND f.clafac=fl.clafac  AND fl.claart=a.claart  AND a.clacat=21 AND year(f.fecha)=2012
  4. GROUP BY c.clacli

Por otro lado
Código MySQL:
Ver original
  1. SELECT c2.clacli AS 'CÓDIGO', c2.nombre AS 'NOMBRE', c2.direccion AS 'DIRECCIÓN', c2.localidad AS 'LOCALIDAD', c2.telefono AS 'TELÉFONO', c2.contacto AS 'CONTACTO', c2.provincia AS 'PROVINCIA', tar.nombre AS 'TARIFA'
  2. FROM clientes c2, tiposcli tipos, codpais cod, tarifa tar
  3. WHERE c2.clatar=tar.clatar
  4. AND c2.clatip=tipos.clatip
  5. AND c2.clapai=cod.clapai
  6. GROUP BY c2.clacli


Como puedo hacer que salgan los datos de ambas tablas cuando coincidan los clacli¿? Creo que se puede pero nunca lo hice y estoy buscando y no encuentro nada al respecto.

Última edición por gnzsoloyo; 09/11/2012 a las 09:39 Razón: Código SQL sin etiquetar. Poco legible,.
  #4 (permalink)  
Antiguo 09/11/2012, 05:31
Avatar de Heimish2000  
Fecha de Ingreso: enero-2011
Ubicación: Madrid
Mensajes: 844
Antigüedad: 13 años, 2 meses
Puntos: 89
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Con un JOIN

Código SQL:
Ver original
  1. SELECT *
  2. FROM (SELECT c.clacli, SUM((fl.precio-((fl.precio*fl.dto)/100))*fl.cantidad) AS 'TOTAL 2012'
  3. FROM clientes c, factura f, factural fl, articulo a
  4. WHERE c.clacli=f.clacli AND f.clafac=fl.clafac AND fl.claart=a.claart AND a.clacat=21 AND YEAR(f.fecha)=2012
  5. GROUP BY c.clacli) AS A
  6. INNER JOIN (
  7. SELECT c2.clacli AS 'CÓDIGO', c2.nombre AS 'NOMBRE', c2.direccion AS 'DIRECCIÓN', c2.localidad AS 'LOCALIDAD', c2.telefono AS 'TELÉFONO', c2.contacto AS 'CONTACTO', c2.provincia AS 'PROVINCIA', tar.nombre AS 'TARIFA'
  8. FROM clientes c2, tiposcli tipos, codpais cod, tarifa tar
  9. WHERE c2.clatar=tar.clatar
  10. AND c2.clatip=tipos.clatip
  11. AND c2.clapai=cod.clapai
  12. GROUP BY c2.clacli) AS B ON
  13. A.clacli = B.CODIGO
  #5 (permalink)  
Antiguo 09/11/2012, 09:16
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Muchas gracias Heimish!
  #6 (permalink)  
Antiguo 09/11/2012, 10:11
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Bueno tras mil y un problemas al final he tenido que hacerlo en una única consulta. Así:

Código MySQL:
Ver original
  1. SELECT c.clacli AS CODIGO, c.nombre AS NOMBRE, c.direccion AS DIRECCION, c.localidad AS LOCALIDAD, c.telefono AS TELEFONO, c.contacto AS CONTACTO, c.provincia AS PROVINCIA, tar.nombre AS TARIFA,
  2.                 ROUND(SUM((fl.precio-((fl.precio*fl.dto)/100))*fl.cantidad), 2) AS TOTAL
  3.                 FROM tiposcli tipos, tarifa tar, codpais cod, clientes c, factura f, factural fl, articulo a
  4.                 WHERE tipos.clatip=c.clatip
  5.                 AND tar.clatar=c.clatar
  6.                 AND cod.clapai=c.clapai
  7.                 AND c.clacli=f.clacli
  8.                 AND fl.clafac=f.clafac
  9.                 AND a.claart=fl.claart
  10.                 AND a.clacat=21
  11.                 AND c.clatip=2                
  12.                 $filtro                
  13.                 GROUP BY c.clacli
La cuestión es que ahora me dicen que deberían salir también los que no tienen resultados. Es decir, un LEFT JOIN. Pero no veo forma humana de convertir eso a LEFT JOIN.

Última edición por gnzsoloyo; 09/11/2012 a las 10:21 Razón: Etiquetado de codigo SQL equivocado.
  #7 (permalink)  
Antiguo 09/11/2012, 10:22
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, 4 meses
Puntos: 2658
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Por favor, alyciashape, cuando pongas código SQL, haz el favor de usar el etiquetado de código correcto.
MySQL no es PHP.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 09/11/2012, 10:31
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Claro. Es que ya lo he intentado y no veo "SQL" por ningún lado. Sólo veo HTML, CODE y PHP por eso entre esos me decidí por PHP.
  #9 (permalink)  
Antiguo 09/11/2012, 10:43
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, 4 meses
Puntos: 2658
Respuesta: Como enlazar multiples tablas. Optimizar consulta

¿Estás segura de lo que dices?
Porque este es el contenido real:

__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #10 (permalink)  
Antiguo 09/11/2012, 10:58
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Ah vaya, Highlight pensé que era para poner un fondo a la letra, en muchos programas es eso sino me equivoco ni se me pasó por la cabeza. Lo que hacía era ir a avanzado para poder poner las etiquetas pinchando en los botones correspondientes, jaja. Para otra ya sé.

De hecho pongámoslo en práctica. He llegado a esto pero algo tiene que estar mal porque me muestra algunos más pero no todos los que no tienen facturas para el citado año:
Código SQL:
Ver original
  1. SELECT c.clacli AS CODIGO, c.nombre AS NOMBRE, c.direccion AS DIRECCION, c.localidad AS LOCALIDAD, c.telefono AS TELEFONO, c.contacto AS CONTACTO, c.provincia AS PROVINCIA, tar.nombre AS TARIFA,
  2. ROUND(SUM((fl.precio-((fl.precio*fl.dto)/100))*fl.cantidad), 2) AS TOTAL           
  3. FROM tiposcli tipos, tarifa tar, codpais cod LEFT JOIN clientes c ON cod.clapai=c.clapai LEFT JOIN factura f ON c.clacli=f.clacli LEFT JOIN factural fl ON f.clafac=fl.clafac LEFT JOIN articulo a ON fl.claart=a.claart
  4. WHERE tipos.clatip=c.clatip
  5. AND tar.clatar=c.clatar                            
  6. AND a.clacat=21
  7. AND c.clatip=2
  8. $filtro                
  9. GROUP BY c.clacli
  10. ORDER BY TOTAL

Es incorrecto mezclar left join con los join normales =?

Es que esos 2 campos que quedan, además de que siempre estan enlazados así que supongo que daría igual, no veo forma de meterlos ahí en medio enlazando con clientes.
  #11 (permalink)  
Antiguo 09/11/2012, 11:08
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, 4 meses
Puntos: 2658
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Cita:
Es incorrecto mezclar left join con los join normales =?
No, pero tienes que tener cuidado en la lógica de resolución de ambos.
Un left join te devovlerá nulos donde no haya coincidencias, por lo que todo INNER JOIN que se apoye en los datos resultados de la tabla izquierda devolverá nulos en ese caso.
Hay que analizar con cuidado los resultados que se obtienen y las relaciones que se establecen.
Por otro lado, en ciertas ocasiones, cuando se realizan JOINs en forma de estrella, pueden generarse productos cartesianos sin que te des cuenta.
Combinar múltiples tablas no es una tarea sencilla.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #12 (permalink)  
Antiguo 09/11/2012, 11:14
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Si, puedo confirmar que es una difícil tarea.

He intentado simplificar que es lo que me suele funcionar cuando no me libro de algún problema, pero aún así no logro lo que quiero. Partiendo de esta simple consulta, me muestra sólo los clientes que TIENEN facturas pero yo quiero ver también los que no compraron nada este año.

Código SQL:
Ver original
  1. SELECT clientes.clacli, nombre, SUM(factural.precio) AS total
  2. FROM clientes
  3. LEFT JOIN factura ON clientes.clacli=factura.clacli
  4. LEFT JOIN factural ON factura.clafac=factural.clafac
  5. WHERE localidad='VIGO' AND YEAR(factura.fecha)=2012
  6. GROUP BY clientes.clacli
  7. ORDER BY total

Puedo asegurar que hay clientes que no compraron NADA pero sólo salen los que si compraron. Y creo que el orden está bien y la sintaxis y todo. Acaso puse algo mal?
  #13 (permalink)  
Antiguo 09/11/2012, 11:23
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, 4 meses
Puntos: 2658
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Empecemos por esto:
Código MySQL:
Ver original
  1. SELECT clientes.clacli, nombre, COUNT(factura.fecha) Facturas
  2. FROM clientes
  3.     LEFT JOIN factura ON clientes.clacli=factura.clacli
  4. WHERE localidad='VIGO' AND YEAR(factura.fecha)=2012
  5. GROUP BY clientes.clacli
  6. ORDER BY total
¿Que te devuelve y cuántos registros?
__________________
¿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 09/11/2012, 11:28
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Pues me devuelve no se, unos 100 registros y todos tienen como mínimo, 1 factura. Digamos que unos cien.

Esto me devuelve unos 1050 registros
SELECT count(nombre) FROM clientes WHERE localidad='VIGO'

¿Así que en la otra consulta deberían salir los 900 restantes no?
  #15 (permalink)  
Antiguo 09/11/2012, 11:29
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, 4 meses
Puntos: 2658
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Los 900 restantes no tienen la fecha del año 2012.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #16 (permalink)  
Antiguo 09/11/2012, 11:30
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Pero 2012 es la fecha de emision de la factura no del cliente. No tendrían que salir?

Tiene que aver una forma de sacar los clientes que tengan y no tengan facturas en 2012.
  #17 (permalink)  
Antiguo 09/11/2012, 11:32
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, 4 meses
Puntos: 2658
Respuesta: Como enlazar multiples tablas. Optimizar consulta

¿QUé contiene el campo CLACLI en ambas tablas?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #18 (permalink)  
Antiguo 09/11/2012, 11:34
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

clacli es el identificador del cliente (clave cliente) si, la bd esta tiene unos nombres horribles, especialmente para mi que suelo poner nombres completos como id_cliente.

Y si a partir de esto:
Código SQL:
Ver original
  1. SELECT clientes.clacli, nombre, SUM(factural.precio) AS total
  2. FROM clientes
  3. LEFT JOIN factura ON clientes.clacli=factura.clacli
  4. LEFT JOIN factural ON factura.clafac=factural.clafac
  5. WHERE localidad='VIGO' AND YEAR(factura.fecha)=2012
  6. GROUP BY clientes.clacli
  7. ORDER BY total

De alguna forma hacer otro select que me saque los clientes que NO estén en ese select. Aunque no sé la sintaxis.

Pero aún así yo creo que lo de antes tendría que funcionar.
  #19 (permalink)  
Antiguo 09/11/2012, 12:21
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, 4 meses
Puntos: 2658
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Si entiendo correctamente, FACTURA es el encabezado de la factura, con los datos de la emisión de la misma, y FACTURAL, son los items correspondientes
Ahora bien, si eso es correcto, entonces la consulta así debería funcionar:
Código MySQL:
Ver original
  1. SELECT C.clacli, C.nombre, SUM(FL.precio) total
  2. FROM clientes C LEFT JOIN factura F ON C.clacli = C.clacli
  3.      INNER JOIN factural FL ON F.clafac = FL.clafac
  4. WHERE localidad='VIGO' AND YEAR(F.fecha)=2012
  5.      OR F.clafac IS NULL
  6. GROUP BY C.clacli
  7. ORDER BY total
En el segundo JOIN debe ponerse INNER JOIN y no LEFT JOIN, porque puede haber clientes sin factura, pero jamás puede existir una factura que no tenga items.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #20 (permalink)  
Antiguo 10/11/2012, 08:48
 
Fecha de Ingreso: abril-2012
Mensajes: 590
Antigüedad: 12 años
Puntos: 58
Respuesta: Como enlazar multiples tablas. Optimizar consulta

Lo tengo que probar aún pero tiene toda la pinta de ser lo que necesitaba. Muchas gracias!

Etiquetas: enlazar, join, multiples, select, tabla, tablas, tipo, campos
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 08:11.