Ver Mensaje Individual
  #5 (permalink)  
Antiguo 16/04/2009, 07:07
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Busqueda de datos entre barias tablas.

El problema es en apariencia complicado, pero en realidad no lo es tanto.
El tema de base es que tienes los datos demasiado separados en tablas diferentes, a pesar de que ciertos datos son parte de la misma entidad, como es el caso de titulo e ISBN (El ISBN es único para cada edición de un título por una editorial y eso incluye tamaño, hojas, presentación y varias cosas más).
Pero para el caso la solución está dentro de lo que te planteó flaviovich en su post: Lo mejor es hacer que la búsqueda se realice sobre un conjunto de registros en los que ya se hayan depurado cualquier tipo de duplicaciones y faltas de datos.
Esto:
Código sql:
Ver original
  1. SELECT  *
  2. FROM  libro1 L1
  3.     INNER JOIN libro2 L2 USING(id)
  4.     INNER JOIN libro3 L3 USING(id)
  5.     INNER JOIN libro4 L4 USING(id)

Te debería devolver una tabla que contenga la totalidad de libros con su serial, titulo, autor e ISBN, por lo que debería ser suficiente para hacer la búsqueda.
El problema que le veo es que deben forzosamente existir TODAS las coincidencias para que te devuelva registros. Si alguna de las tablas no ha sido llenada con el id vinculado, ese registro no será devuelto, a pesar de que exista el resto de los datos (por ejemplo, si falta ingresar un ISBN, o un autor). En ese sentido es mejor usar LEFT JOIN, que te devuelve los resultantes, aunque sean nulos:
Código sql:
Ver original
  1. SELECT   titulo, IFNULL(autor,'') Autor, IFNULL(serial,'') serial, IFNULL(isbn,'') ISBN
  2. FROM  libro2 L2
  3.     LEFT JOIN libro1 L1 USING(id)
  4.     LEFT JOIN libro3 L3 USING(id)
  5.     LEFT JOIN libro4 L4 USING(id)

Verás que he incluido una función IFNULL(), eso es para evitar que los NULL aparezcan, sino que representa caracteres vacíos (NULL <> ''). También notarás que cambié el orden de los JOIN. Eso es porque un libro debe tener forzosamente título para figurar, aunque no se tenga ni autor, ni serial ni isbn. El tema allí es que la primera tabla tiene que devolver si o si valores y no nulos, de lo contrario, la consulta no devolverá el registro.

Finalmente, yo esto lo resolvería por una vista o por una subconsulta, para no complicarle la resolución al parser de MySQL.
Con una vista:
Código sql:
Ver original
  1. CREATE O REPLACE VIEW listaLibros AS
  2. SELECT   titulo, IFNULL(autor,'') Autor, IFNULL(serial,'') serial, IFNULL(isbn,'') ISBN
  3. FROM  libro2 L2
  4.     LEFT JOIN libro1 L1 USING(id)
  5.     LEFT JOIN libro3 L3 USING(id)
  6.     LEFT JOIN libro4 L4 USING(id);
Esto se debe ejecutar una sola vez y entonces la VIEW estará disponible para:
Código sql:
Ver original
  1. SELECT   titulo, IFNULL(autor,'') Autor, IFNULL(serial,'') serial, IFNULL(isbn,'') ISBN
  2. FROM  listalibros L
  3. WHERE titulo LIKE '%valor%'
  4.    OR autor LIKE '%valor%'
  5.    OR serial LIKE '%valor%'
  6.    OR isbn LIKE '%valor%';

En caso de querer hacerlo directo y sin VIEWs, sería mejor:

Código sql:
Ver original
  1. SELECT   titulo, IFNULL(autor,'') Autor, IFNULL(serial,'') serial, IFNULL(isbn,'') ISBN
  2. FROM  (SELECT   titulo, IFNULL(autor,'') Autor, IFNULL(serial,'') serial, IFNULL(isbn,'') ISBN
  3.             FROM  libro2 L2
  4.                 LEFT JOIN libro1 L1 USING(id)
  5.                 LEFT JOIN libro3 L3 USING(id)
  6.                 LEFT JOIN libro4 L4 USING(id)) L
  7. WHERE titulo LIKE '%valor%'
  8.    OR autor LIKE '%valor%'
  9.    OR serial LIKE '%valor%'
  10.    OR isbn LIKE '%valor%';
Pruébalo y me cuentas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)