Listado completo de tutoriales

75 - Insertar datos en una tabla buscando un valor en otra (insert - select)


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

La tabla "libros" tiene la siguiente estructura:

 -codigo: int unsigned auto_increment,
 -titulo: varchar(40) not null,
 -autor: varchar(30),
 -codigoeditorial: tinyint unsigned,
 -precio: decimal(5,2) unsigned,
 -clave primaria: codigo.

La tabla "editoriales" tiene la siguiente estructura:

 -codigo: tinyint unsigned auto_increment,
 -nombre: varchar(20),
 -domicilio: varchar(30),
 -clave primaria: codigo.

Ambas tablas contienen registros. La tabla "editoriales" contiene los siguientes registros:

 1,Planeta,San Martin 222,
 2,Emece,San Martin 590,
 3,Paidos,Colon 245.

Queremos ingresar en "libros", el siguiente libro: Harry Potter y la piedra filosofal, J.K. Rowling, Emece, 45.90.

pero no recordamos el código de la editorial "Emece".

Podemos lograrlo en 2 pasos:

1º paso: consultar en la tabla "editoriales" el código de la editorial "Emece":

  select codigo
  from editoriales
  where nombre='Emece';

nos devuelve el valor "2".

2º paso: ingresar el registro en "libros":

 insert into libros (titulo,autor,codigoeditorial,precio)
  values('Harry Potter y la piedra filosofal','J.K.Rowling',2,45.90);

O podemos realizar la consulta del código de la editorial al momento de la inserción:

 insert into libros (titulo,autor,codigoeditorial,precio)
  select 'Harry Potter y la camara secreta','J.K.Rowling',codigo,45.90
  from editoriales
  where nombre='Emece';

Entonces, para realizar una inserción y al mismo tiempo consultar un valor en otra tabla, colocamos "insert into" junto al nombre de la tabla ("libros") y los campos a insertar y luego un "select" en el cual disponemos todos los valores, excepto el valor que desconocemos, en su lugar colocamos el nombre del campo a consultar ("codigo"), luego se continúa con la consulta indicando la tabla de la cual extraemos el código ("editoriales") y la condición, en la cual damos el "nombre" de la editorial para que localice el código correspondiente.

El registro se cargará con el valor de código de la editorial "Emece".

Si la consulta no devuelve ningún valor, porque buscamos el código de una editorial que no existe en la tabla "editoriales", aparece un mensaje indicando que no se ingresó ningún registro. Por ejemplo:

 insert into libros (titulo,autor,codigoeditorial,precio)
  select 'Cervantes y el quijote','Borges',codigo,35
  from editoriales
  where nombre='Plaza & Janes';

Hay que tener cuidado al establecer la condición en la consulta, el "insert" ingresará tantos registros como filas retorne la consulta. Si la consulta devuelve 2 filas, se insertarán 2 filas en el "insert". Por ello, el valor de la condición (o condiciones), por el cual se busca, debe retornar un sólo registro.

Veamos un ejemplo. Queremos ingresar el siguiente registro:

 Harry Potter y la camara secreta, J.K. Rowling,54.

pero no recordamos el código de la editorial ni su nombre, sólo sabemos que su domicilio es en calle "San Martin". Si con un "select" localizamos el código de todas las editoriales que tengan sede en "San Martin", el resultado retorna 2 filas, porque hay 2 editoriales en esa dirección ("Planeta" y "Emece"). Tipeeemos la sentencia:

 insert into libros (titulo,autor,codigoeditorial,precio)
  select 'Harry Potter y la camara secreta','J.K. Rowling',codigo,54
  from editoriales
  where domicilio like 'San Martin%';

Se ingresarán 2 registros con los mismos datos, excepto el código de la editorial.

Recuerde entonces, el valor de la condición (condiciones), por el cual se busca el dato desconocido en la consulta debe retornar un sólo registro.

También se pueden consultar valores de varias tablas incluyendo en el "select" un "join". Veremos ejemplos en "Ejercicios propuestos".

Servidor de MySQL instalado en forma local.

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

 drop tables if exists libros, editoriales;

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

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


 insert into libros values (1,'El aleph','Borges',2,23.5);
 insert into libros values (2,'Alicia en el pais de las maravillas','Lewis Carroll',1,15);
 insert into libros values (3,'Matematica estas ahi','Paenza',2,34.6);
 insert into libros values (4,'Martin Fierro','Jose Hernandez',3,43.5);
 insert into libros values (5,'Martin Fierro','Jose Hernandez',2,12);

 insert into editoriales values(1,'Planeta','San Martin 222');
 insert into editoriales values(2,'Emece','San Martin 590');
 insert into editoriales values(3,'Paidos','Colon 245');

 insert into libros (titulo,autor,codigoeditorial,precio)
  select 'Harry Potter y la camara secreta','J.K.Rowling',codigo,45.90
  from editoriales
  where nombre='Emece';
  -- El registro se cargará con el valor de código de la editorial "Emece".

 -- Veamos qué sucedió:
 select * from libros;

  -- Si buscamos el código de una editorial que no existe en la tabla "editoriales",
  -- la consulta no retornará ningún registro y la inserción no se realizará. Veamos
  -- un ejemplo:
 insert into libros (titulo,autor,codigoeditorial,precio)
  select 'Cervantes y el quijote','Borges',codigo,35
  from editoriales
  where nombre='Plaza & Janes';


 -- Queremos ingresar el siguiente registro:
 -- Harry Potter y la camara secreta, J.K. Rowling,54.
 -- pero no recordamos el código de la editorial ni su nombre, sólo sabemos que su 
 -- domicilio es en calle "San Martin". Si con un "select" localizamos 
 -- el código de todas las editoriales que tengan sede en "San Martin",
 -- el resultado retorna 2 filas, porque hay 2 editoriales en esa dirección 
 -- ("Planeta" y "Emece"). Tipeeemos la sentencia:
 insert into libros (titulo,autor,codigoeditorial,precio)
  select 'Harry Potter y la camara secreta','J.K. Rowling',codigo,54
  from editoriales
  where domicilio like 'San Martin%';

 -- Veamos qué sucedió:
 select * from libros;

Genera una salida similar a esta:

MySQL insert con select

Retornar