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:
1DELETE FROM inscripciones AS i2WHERE (i.id_alumno = 140)3AND (i.id_materia = (4 SELECT id_materia5 FROM materias6 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:
1UPDATE t1 SET c1 = (subcon1)2WHERE 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:
1INSERT INTO t1 (c1, c2, c3)2VALUES ((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:
1INSERT INTO t1 (c1, c2)2 SELECT t2.c4, t3.c33 FROM t2 JOIN t34 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
.