Listado completo de tutoriales

67 - Varias tablas (natural join)


"natural join" se usa cuando los campos por los cuales se enlazan las tablas tienen el mismo nombre.

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

Las tablas tienen las siguientes estructuras:

 - libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio.
 - editoriales: codigoeditorial(clave primaria), nombre.

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;

Es decir, con "natural join" no se coloca la parte "on" que especifica los campos por los cuales se enlazan las tablas, porque MySQL busca los campos con igual nombre y enlaza las tablas por ese campo.

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. Por ejemplo, si el campo "titulo" de la tabla "libros" se llamara "nombre", las tablas tendrían 2 campos con igual nombre ("codigoeditorial" y "nombre").

Otro problema que puede surgir es el siguiente. Tenemos la tabla "libros" con los siguientes campos: codigo (del libro), titulo, autor y codigoeditorial, y la tabla "editoriales" con estos campos: codigo (de la editorial) y nombre. 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.

Servidor de MySQL instalado en forma local.

Ingresemos al programa "Workbench" y ejecutemos el siguiente bloque de instrucciones SQL:

 drop table if exists libros, editoriales;

 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)
 );

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

 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;

Genera una salida similar a esta:

MySQL natural join

Retornar