Saltearse al contenido

Subconsultas con otras sentencias

Entre las otras sentencias, además de SELECT, con las que podemos hacer uso de subconsultas, mencionaremos a UPDATE y DELETE. Para estas, el uso más común de las subconsultas es en la cláusula WHERE, para restringir los registros afectados, como ya vimos antes con SELECT.

Por ejemplo, si tenemos una base de datos con las tablas: alumnos, materias e inscripciones, donde esta última es una tabla intermedia entre las otras dos, y en ella se almacena la fecha de inscripción y la calificación final del alumno.

A continuación, se puede apreciar esta sección del DER de la base de datos:

Digamos que, por error, se insertó un registro incorrecto de inscripción para el alumno con id 140, en la materia “Física” y queremos eliminar ese registro.

Para eliminar el registro tenemos que indicar ambos valores para las claves foráneas. Ya tenemos el valor de una (el id_alumno 140), pero nos falta el id de la materia “Física”. Para obtenerlo vamos a utilizar una subconsulta ya que sabemos que solo existe una materia con nombre “Física”. Entonces, la consulta quedaría de la siguiente forma:

1
DELETE FROM inscripciones AS i
2
WHERE (i.id_alumno = 140)
3
AND (i.id_materia = (
4
SELECT id_materia
5
FROM materias
6
WHERE nombre = "Física")
7
);

Por otro lado, en una sentencia UPDATE, además de poder utilizar subconsultas en la cláusula WHERE, es posible indicar un valor a modificar en la cláusula SET mediante una subconsulta que devuelva un escalar.

Por ejemplo:

1
UPDATE t1 SET c1 = (subcon1)
2
WHERE c2 = (subcon2);

En el ejemplo genérico, podemos ver las dos formas de usar subconsultas en una sentencias UPDATE.

La subconsulta subcon1 debe obtener solo un valor, que se va a escribir en el campo c1 de t1, para todos los registros que cumplan con la condición en WHERE.

A su vez, subcon2 también debe obtener un solo valor para igualar con c2, a menos que se utilice un modificador como ANY, IN o ALL, en tal caso, podrán modificarse varios registros.

Subconsultas con la sentencia INSERT

En primer lugar, recordemos que la sentencia INSERT no permite la cláusula WHERE, donde usamos comúnmente las subconsultas. De todas formas INSERT soporta subconsultas dentro de la cláusula VALUES, en donde podemos especificar subconsultas que devuelven escalares, que tomarán el lugar de los valores a insertar.

Por ejemplo:

1
INSERT INTO t1 (c1, c2, c3)
2
VALUES ((
3
SELECT c5 FROM t2 WHERE <condicion1>
4
), (
5
SELECT c8 FROM t3 WHERE <condicion2>
6
), "100");

En este caso las subconsultas que usamos deben tener condiciones, condicion1 y condicion2, que restrinjan los resultados de cada consulta a un único valor, ya que estamos insertando un solo registro. Para el tercer valor simplemente indicamos un literal a modo de ejemplo.

Además, las subconsultas deben ejecutarse sobre tablas distintas a t1, ya que MySQL no permite una subconsulta sobre la misma tabla en la que se inserta.

La sentencia INSERT ... SELECT

Por otro lado, la sentencia INSERT permite una sintaxis particular similar a las subconsultas. A través de la sentencia compuesta INSERT ... SELECT.

En este caso la subconsulta devuelve uno o más registros que luego se insertarán en la tabla sobre la que se ejecuta el INSERT.

Esta consulta tiene la forma:

1
INSERT INTO t1 (c1, c2)
2
SELECT t2.c4, t3.c3
3
FROM t2 JOIN t3
4
WHERE t2.c4 > 100;

Observar que la subconsulta, en este caso particular, no va entre paréntesis, ya que es parte de la sintaxis de la sentencia INSERT.

Al usar una subconsulta para insertar registros, la subconsulta debe obtener la misma cantidad y tipo de valores que figuran en la lista de campos a insertar.

En nuestro ejemplo, lo retornado por t2.c4 y t3.c3 debe ser del mismo tipo que t1.c1 y t1.c2 respectivamente. Y la cantidad de campos obtenidos en el SELECT debe ser igual a la cantidad de campos a insertar.

De esta manera, podemos insertar una gran cantidad de registros a una tabla a partir de una consulta a una o más tablas.

Cabe aclarar, que en este caso, la tabla a la que estamos insertando puede figurar en la cláusula FROM de la consulta SELECT.

Bibliografía

  1. MySQL Docs - Insert-Select