53 - Subconsulta (update - delete)

Dijimos que podemos emplear subconsultas en sentencias "insert", "update", "delete", además de "select".

La sintaxis básica para realizar actualizaciones con subconsulta es la siguiente:

 update TABLA set CAMPO=NUEVOVALOR
  where CAMPO= (SUBCONSULTA);

Actualizamos el precio de todos los libros de editorial "Emece":

 update libros set precio=precio+(precio*0.1)
  where codigoeditorial=
   (select codigo
     from editoriales
     where nombre='Emece');

La subconsulta retorna un único valor. También podemos hacerlo con un join.

La sintaxis básica para realizar eliminaciones con subconsulta es la siguiente:

 delete from TABLA
  where CAMPO in (SUBCONSULTA);

Eliminamos todos los libros de las editoriales que tiene publicados libros de "Juan Perez":

 delete from libros
  where codigoeditorial in
   (select e.codigo
    from editoriales as e
    join libros
    on codigoeditorial=e.codigo
    where autor='Juan Perez');

La subconsulta es una combinación que retorna una lista de valores que la consulta externa emplea al seleccionar los registros para la eliminación.

Problema resuelto

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

Borramos las tablas si ya existen:

drop table if exists libros;
drop table if exists editoriales;

Creamos las dos tablas con las siguientes estructuras:

create table libros(
	codigo integer primary key,
	titulo text,
	autor text, 
	precio real,
	codigoeditorial integer	
);

create table editoriales(
	codigo integer primary key,
	nombre text
);

Almacenamos algunos datos para hacer pruebas:

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

 insert into libros(titulo,autor,codigoeditorial,precio) 
   values('Uno','Richard Bach',1,15);
 insert into libros(titulo,autor,codigoeditorial,precio)
   values('Ilusiones','Richard Bach',2,20);
 insert into libros(titulo,autor,codigoeditorial,precio)
   values('El aleph','Borges',3,10);
 insert into libros(titulo,autor,codigoeditorial,precio)
   values('Aprenda PHP','Mario Molina',4,40);
 insert into libros(titulo,autor,codigoeditorial,precio)
   values('Poemas','Juan Perez',1,20);
 insert into libros(titulo,autor,codigoeditorial,precio)
   values('Cuentos','Juan Perez',3,25);
 insert into libros(titulo,autor,codigoeditorial,precio)
   values('Java en 10 minutos','Marcelo Perez',2,30);

Actualizamos el precio de todos los libros de editorial "Emece" incrementándolos en un 10%:

 update libros set precio=precio+(precio*0.1)
  where codigoeditorial=
   (select codigo
     from editoriales
     where nombre='Emece');   

Eliminamos todos los libros de las editoriales que tiene publicados libros de "Juan Perez":

 delete from libros
  where codigoeditorial in
   (select e.codigo
    from editoriales as e
    join libros
    on codigoeditorial=e.codigo
    where autor='Juan Perez');	 

Problema propuesto

Un club dicta clases de distintos deportes a sus socios. El club tiene una tabla llamada "inscriptos" en la cual almacena el número de "socio", el código del deporte en el cual se inscribe y si la matricula está o no paga, y una tabla denominada "socios" en la que guarda los datos personales de cada socio.

  1. Borrar las tablas "socios" e "inscriptos" si existen.

  2. Crear las tablas con las siguientes estructuras:

     create table socios(
      numero integer primary key,
      documento text,
      nombre text,
      domicilio text
     );
     
     create table inscriptos (
      numerosocio integer,
      deporte text,
      matricula text,-- 'n' o 's'
      primary key(numerosocio,deporte)
     );
    
  3. Almacenar algunas filas para hacer las pruebas:

     insert into socios(documento,nombre,domicilio) values('23333333','Alberto Paredes','Colon 111');
     insert into socios(documento,nombre,domicilio) values('24444444','Carlos Conte','Sarmiento 755');
     insert into socios(documento,nombre,domicilio) values('25555555','Fabian Fuentes','Caseros 987');
     insert into socios(documento,nombre,domicilio) values('26666666','Hector Lopez','Sucre 344');
    
     insert into inscriptos values(1,'tenis','s');
     insert into inscriptos values(1,'basquet','s');
     insert into inscriptos values(1,'natacion','s');
     insert into inscriptos values(2,'tenis','s');
     insert into inscriptos values(2,'natacion','s');
     insert into inscriptos values(2,'basquet','n');
     insert into inscriptos values(2,'futbol','n');
     insert into inscriptos values(3,'tenis','s');
     insert into inscriptos values(3,'basquet','s');
     insert into inscriptos values(3,'natacion','n');
     insert into inscriptos values(4,'basquet','n');
    
  4. Actualizamos la cuota ('s') de todas las inscripciones de un socio determinado (por documento) empleando subconsulta.

  5. Elimine todas las inscripciones de los socios que deben alguna matrícula.

Solución
 drop table if exists socios;
 drop table if exists inscriptos;
 
 create table socios(
  numero integer primary key,
  documento text,
  nombre text,
  domicilio text
 );
 
 create table inscriptos (
  numerosocio integer,
  deporte text,
  matricula text,-- 'n' o 's'
  primary key(numerosocio,deporte)
 );
 
 insert into socios(documento,nombre,domicilio) values('23333333','Alberto Paredes','Colon 111');
 insert into socios(documento,nombre,domicilio) values('24444444','Carlos Conte','Sarmiento 755');
 insert into socios(documento,nombre,domicilio) values('25555555','Fabian Fuentes','Caseros 987');
 insert into socios(documento,nombre,domicilio) values('26666666','Hector Lopez','Sucre 344');

 insert into inscriptos values(1,'tenis','s');
 insert into inscriptos values(1,'basquet','s');
 insert into inscriptos values(1,'natacion','s');
 insert into inscriptos values(2,'tenis','s');
 insert into inscriptos values(2,'natacion','s');
 insert into inscriptos values(2,'basquet','n');
 insert into inscriptos values(2,'futbol','n');
 insert into inscriptos values(3,'tenis','s');
 insert into inscriptos values(3,'basquet','s');
 insert into inscriptos values(3,'natacion','n');
 insert into inscriptos values(4,'basquet','n'); 
 

 update inscriptos set matricula='s'
  where numerosocio=
   (select numero
     from socios
     where documento='25555555'); 
	 

 delete from inscriptos
  where numerosocio in
   (select numero
    from socios as s
    join inscriptos
    on numerosocio=numero
    where matricula='n');	 

Ejecución de ejercicios online

Puede ejecutar comandos de SQLite directamente en el sitio sin tener que instalar nada en su computadora.

Resultado.....