64 - Varias tablas (left join)


Problema:

Trabajamos con las tablas "libros" y editoriales" de una librería.

Eliminamos dichas tablas, si existen:

 drop table if exists libros, editoriales;

Creamos las siguientes tablas:

 create table libros(
  codigo int unsigned auto_increment,
  titulo varchar(40) not null,
  autor varchar(30) not null default 'Desconocido',
  codigoeditorial tinyint unsigned not null,
  precio decimal(5,2) unsigned,
  cantidad tinyint unsigned default 0,
  primary key (codigo)
 );

 create table editoriales(
  codigo tinyint unsigned auto_increment,
  nombre varchar(20) not null,
  primary key(codigo)
 );

Cargamos algunos registros en la tabla "editoriales":

 insert into editoriales (nombre) values('Paidos');
 insert into editoriales (nombre) values('Emece');
 insert into editoriales (nombre) values('Planeta');
 insert into editoriales (nombre) values('Sudamericana');

Cargamos algunos registros en la tabla "libros":

 insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
  values('El Aleph','Borges',3,43.5,200);
 insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
  values('Alicia en el pais de las maravillas','Lewis Carroll',2,33.5,100);
 insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
  values('Aprenda PHP','Mario Perez',1,55.8,50);
 insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
  values('Java en 10 minutos','Juan Lopez',1,88,150);
 insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
  values('Alicia a traves del espejo','Lewis Carroll',1,15.5,80);
 insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
  values('Cervantes y el quijote','Borges- Bioy Casares',3,25.5,250);
 insert into libros (titulo, autor,codigoeditorial,precio,cantidad)
  values('Aprenda Java en 10 minutos','Lopez Juan',5,28,100);

Para obtener la lista de todas las editoriales y los libros de las mismas, incluso de las cuales no tenemos libros usamos:

 select * from editoriales
  left join libros
  on editoriales.codigo=libros.codigoeditorial;

Un "left join" se usa para hacer coincidir registros en una tabla (izquierda) con otra tabla (derecha), pero, si un valor de la tabla de la izquierda no encuentra coincidencia en la tabla de la derecha, se genera una fila extra (una por cada valor no encontrado) con todos los campos seteados a "null".

Recuerde que es importante la posición en que se colocan las tablas en un "left join", la tabla de la izquierda es la que localiza registros en la tabla de la derecha. Por lo tanto, estos "join" no son iguales:

 select * from editoriales
 left join libros
 on editoriales.codigo=libros.codigoeditorial;

 select * from libros
  left join editoriales
  on editoriales.codigo=libros.codigoeditorial;

La primera sentencia busca coincidencia en la tabla "libros" por cada valor de codigo de "editoriales", si no encuentra coincidencia para algún valor, genera una fila seteada a "null". No hay libros de la editorial "Sudamericana", entonces esa fila contiene "null" en todos los campos correspondientes a "libros".

La segunda sentencia busca coincidencia en la tabla "editoriales" por cada valor de "codigoeditorial" de "libros", si no encuentra coincidencia para algún valor, genera una fila seteada a "null". El libro "Aprenda java en 10 minutos" tiene código de editorial "5", valor inexistente en la tabla "editoriales", por ello, esa fila contiene "null" en todos los campos correspondientes a "editoriales".

Para encontrar los valores de código de la tabla "editoriales" que están presentes en la tabla "libros" usamos un "where":

 select nombre,titulo
  from editoriales as e
  left join libros as l
  on e.codigo=l.codigoeditorial
  where l.codigoeditorial is not null;

Para mostrar las editoriales que no están presentes en "libros":

 select e.nombre,l.titulo from editoriales as e
  left join libros as l
  on e.codigo=l.codigoeditorial
  where l.codigoeditorial is null;



Retornar