67 - Varias tablas (natural 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(
  codigoeditorial tinyint unsigned auto_increment,
  nombre varchar(20) not null,
  primary key(codigoeditorial)
 );

Cargamos algunos registros en la tabla "editoriales":

 insert into editoriales (nombre) values('Planeta');
 insert into editoriales (nombre) values('Emece');
 insert into editoriales (nombre) values('Paidos');
 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',1,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('Martin Fierro','Jose Hernandez',1,55.8,50);

Como en ambas tablas, el código de la editorial se denomina "codigoeditorial", podemos omitir la parte "on" que indica los nombres de los campos por el cual se enlazan las tablas, empleando "natural join", se unirán por el campo que tienen en común:

 select titulo,nombre
  from libros as l
  natural join editoriales as e;

La siguiente sentencia tiene la misma salida anterior:

 select titulo,nombre
  from libros as l
  join editoriales as e
  on l.codigoeditorial=e.codigoeditorial;

También se puede usar "natural" con "left join" y "right join":

 select nombre,titulo
  from editoriales as e
  natural left join libros as l;

que tiene la misma salida que:

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

Hay que tener cuidado con este tipo de "join" porque si ambas tablas tiene más de un campo con igual nombre, MySQL no sabrá por cual debe realizar la unión.

Alteremos la tabla "libros" para que el campo "titulo" se denomine "nombre":

 alter table libros change titulo nombre varchar(40);

Ahora las tablas tienen 2 campos con igual nombre ("codigoeditorial" y "nombre"). Intentemos realizar un "natural join":

 select l.nombre,e.nombre
  from libros as l
  natural join editoriales as e;

No hay salida.

Alteramos nuevamente la tabla "libros" para que el campo "nombre" en adelante sea "titulo":

 alter table libros change nombre titulo varchar(40);

Alteramos la tabla "editoriales" para que el campo "codigoeditorial" se llame en adelante "codigo":

 alter table editoriales change codigoeditorial codigo tinyint unsigned auto_increment;

Si usamos "natural join", unirá las tablas por el campo "codigo", que es el campo que tienen igual nombre, pero el campo "codigo" de "libros" no hace referencia al código de la editorial sino al del libro, así que la salida será errónea:

select l.*,e.*
 from libros as l
 natural join editoriales as e;

Note que el libro con código "3" de editorial "Planeta" aparece como perteneciente a la editorial "Paidos" (código 3) porque buscó coincidencia del código del libro con el código de editorial.




Retornar