Vimos que una subconsulta puede reemplazar una expresión. Dicha subconsulta debe devolver un valor escalar o una lista de valores de un campo; las subconsultas que retornan una lista de valores reemplazan a una expresión en una cláusula "where" que contiene la palabra clave "in".
El resultado de una subconsulta con "in" (o "not in") es una lista. Luego que la subconsulta retorna resultados, la consulta exterior los usa.
La sintaxis básica es la siguiente:
...where EXPRESION in (SUBCONSULTA);
Este ejemplo muestra los nombres de las editoriales que han publicado libros de un determinado autor:
select nombre from editoriales where codigo in (select codigoeditorial from libros where autor='Richard Bach');
La subconsulta (consulta interna) retorna una lista de valores de un solo campo (codigo) que la consulta exterior luego emplea al recuperar los datos.
Podemos reemplazar por un "join" la consulta anterior:
select distinct nombre from editoriales as e join libros on codigoeditorial=e.codigo where autor='Richard Bach';
Una combinación (join) siempre puede ser expresada como una subconsulta; pero una subconsulta no siempre puede reemplazarse por una combinación que retorne el mismo resultado. Si es posible, es aconsejable emplear combinaciones en lugar de subconsultas, son más eficientes.
Se recomienda probar las subconsultas antes de incluirlas en una consulta exterior, así puede verificar que retorna lo necesario, porque a veces resulta difícil verlo en consultas anidadas.
También podemos buscar valores No coincidentes con una lista de valores que retorna una subconsulta; por ejemplo, las editoriales que no han publicado libros de un autor específico:
select nombre from editoriales where codigo not in (select codigoeditorial from libros where autor='Richard Bach');
Trabajamos con las tablas "libros" y "editoriales" de una librería.
Eliminamos las tablas si ya existen:
drop table if exists libros; drop table if exists editoriales;
Creamos las dos tablas:
create table libros( codigo integer primary key, titulo text, autor text, precio real, codigoeditorial integer ); create table editoriales( codigo integer primary key, nombre text );
Insertamos una serie de filas en cada tabla:
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) values('Uno','Richard Bach',1); insert into libros(titulo,autor,codigoeditorial) values('Ilusiones','Richard Bach',1); insert into libros(titulo,autor,codigoeditorial) values('Aprenda PHP','Mario Molina',4); insert into libros(titulo,autor,codigoeditorial) values('El aleph','Borges',2); insert into libros(titulo,autor,codigoeditorial) values('Puente al infinito','Richard Bach',2);
Queremos conocer el nombre de las editoriales que han publicado libros del autor "Richard Bach":
select nombre from editoriales where codigo in (select codigoeditorial from libros where autor='Richard Bach');
Probamos la subconsulta separada de la consulta exterior para verificar que retorna una lista de valores de un solo campo:
select codigoeditorial from libros where autor='Richard Bach';
Podemos reemplazar por un "join" la primera consulta:
select distinct nombre from editoriales as e join libros on codigoeditorial=e.codigo where autor='Richard Bach';
También podemos buscar las editoriales que no han publicado libros de "Richard Bach":
select nombre from editoriales where codigo not in (select codigoeditorial from libros where autor='Richard Bach');
Una empresa tiene registrados sus clientes en una tabla llamada "clientes", también tiene una tabla "ciudades" donde registra los nombres de las ciudades.
Borrar las tablas "clientes" y "ciudades" si existen.
Crear las tablas con las siguientes estructuras:
create table ciudades( codigo integer primary key, nombre text ); create table clientes ( codigo integer primary key, nombre text, domicilio text, codigociudad integer );
Almacenar las siguientes filas como datos de ejemplo:
insert into ciudades (nombre) values('Cordoba'); insert into ciudades (nombre) values('Cruz del Eje'); insert into ciudades (nombre) values('Carlos Paz'); insert into ciudades (nombre) values('La Falda'); insert into ciudades (nombre) values('Villa Maria'); insert into clientes(nombre,domicilio,codigociudad) values ('Lopez Marcos','Colon 111',1); insert into clientes(nombre,domicilio,codigociudad) values ('Lopez Hector','San Martin 222',1); insert into clientes(nombre,domicilio,codigociudad) values ('Perez Ana','San Martin 333',2); insert into clientes(nombre,domicilio,codigociudad) values ('Garcia Juan','Rivadavia 444',3); insert into clientes(nombre,domicilio,codigociudad) values ('Perez Luis','Sarmiento 555',3); insert into clientes(nombre,domicilio,codigociudad) values ('Gomez Ines','San Martin 666',4); insert into clientes(nombre,domicilio,codigociudad) values ('Torres Fabiola','Alem 777',5); insert into clientes(nombre,domicilio,codigociudad) values ('Garcia Luis','Sucre 888',5);
Necesitamos conocer los nombres de las ciudades de aquellos clientes cuyo domicilio es en calle "San Martin", empleando subconsulta.
Obtenga la misma salida anterior pero empleando join.
Obtenga los nombre de las ciudades de los clientes cuyo apellido no comienza con una letra específica, empleando subconsulta.
Pruebe la subconsulta del punto 5 separada de la consulta exterior para verificar que retorna una lista de valores de un solo campo.
drop table if exists ciudades; drop table if exists clientes; create table ciudades( codigo integer primary key, nombre text ); create table clientes ( codigo integer primary key, nombre text, domicilio text, codigociudad integer ); insert into ciudades (nombre) values('Cordoba'); insert into ciudades (nombre) values('Cruz del Eje'); insert into ciudades (nombre) values('Carlos Paz'); insert into ciudades (nombre) values('La Falda'); insert into ciudades (nombre) values('Villa Maria'); insert into clientes(nombre,domicilio,codigociudad) values ('Lopez Marcos','Colon 111',1); insert into clientes(nombre,domicilio,codigociudad) values ('Lopez Hector','San Martin 222',1); insert into clientes(nombre,domicilio,codigociudad) values ('Perez Ana','San Martin 333',2); insert into clientes(nombre,domicilio,codigociudad) values ('Garcia Juan','Rivadavia 444',3); insert into clientes(nombre,domicilio,codigociudad) values ('Perez Luis','Sarmiento 555',3); insert into clientes(nombre,domicilio,codigociudad) values ('Gomez Ines','San Martin 666',4); insert into clientes(nombre,domicilio,codigociudad) values ('Torres Fabiola','Alem 777',5); insert into clientes(nombre,domicilio,codigociudad) values ('Garcia Luis','Sucre 888',5); select nombre from ciudades where codigo in (select codigociudad from clientes where domicilio like 'San Martin %'); select distinct ci.nombre from ciudades as ci join clientes as cl on codigociudad=ci.codigo where domicilio like 'San Martin%'; select nombre from ciudades where codigo not in (select codigociudad from clientes where nombre like 'G%'); select codigociudad from clientes where nombre like 'G%';
Puede ejecutar comandos de SQLite directamente en el sitio sin tener que instalar nada en su computadora.