Una subconsulta es una forma poderosa de encontrar los datos que desea usar para otra consulta. A menudo se usan en declaraciones SELECT y UPDATE para hacer que estas consultas sean más eficientes y fáciles de mantener.
Hay varias formas diferentes de usar subconsultas en instrucciones UPDATE. Echemos un vistazo a cada uno de ellos.
SET y Subconsulta
El primer método que veremos es usar una subconsulta en la cláusula SET de una instrucción UPDATE.
Digamos que tuviéramos una tabla de productos que se viera así:
[identificación de la tabla=29 /]
Almacena algunos datos sobre los diferentes productos que vende una empresa.
Supongamos que la empresa decidió aumentar el precio del producto "Sofá" (id. de producto 1). Sin embargo, en lugar de establecer un precio específico, quieren que sea un 20 % más alto que el producto más caro que tienen.
Para hacer esto, podemos usar una subconsulta en la cláusula SET. Podríamos usar declaraciones separadas, pero es más fácil de mantener usando una sola declaración.
Nuestra declaración se vería así:
UPDATE product SET price = ( SELECT MAX(price) * 1.2 FROM product ) WHERE product_id = 1;
Puede ver que la cláusula SET incluye una subconsulta, que encuentra el valor MAX de la columna de precio en la tabla de productos y lo multiplica por 1.2 para agregar 20%. Finalmente, la cláusula WHERE está fuera de la subconsulta para actualizar únicamente el product_id de 1, ya que se aplica a ACTUALIZAR en lugar de a la subconsulta.
Esto resultará en el siguiente cambio:
[identificación de la tabla=30 /]
SET y subconsulta correlacionada
Otra forma de usar una subconsulta en una instrucción UPDATE es usar una subconsulta correlacionada.
Funciona de manera similar al ejemplo anterior. Sin embargo, una subconsulta correlacionada es una subconsulta que se refiere a la instrucción externa y puede ser parte de una instrucción UPDATE.
Utilizando los datos del ejemplo anterior (la tabla de productos), la empresa quiere desactivar todos los productos que no han tenido pedido. Los datos para esto se almacenan en la tabla order_line.
Si lo escribimos como una subconsulta correlacionada, la consulta se verá así:
UPDATE product p SET active = ( SELECT CASE WHEN COUNT(*) > 0 THEN 'Y' ELSE 'N' END FROM order_line o WHERE o.product_id = p.product_id );
La subconsulta realizará una función COUNT usando una instrucción CASE para determinar si el valor devuelto es Y o N dependiendo del valor de COUNT. Se calcula para cada product_id y coincide con la consulta externa.
Esto resultará en la columna activa para algunos productos establecidos en Y y otros establecidos en N:
[identificación de la tabla=31 /]
WHERE Mayor que Subconsulta
También es posible utilizar una subconsulta en la cláusula WHERE. Al igual que en los ejemplos anteriores, esto se puede hacer para eliminar el paso separado de encontrar un valor para actualizar y luego ejecutar la consulta para actualizarlo.
Podemos seguir trabajando con nuestro ejemplo de los pasos anteriores. Suponga que la empresa quiere activar productos que tienen un precio superior al promedio. Para hacer esto, podemos agregar una subconsulta a la cláusula WHERE.
Primero, desactive todos los productos.
UPDATE product SET active = ’N’;
Luego, actualice la tabla usando nuestra subconsulta.
UPDATE product SET active = 'Y' WHERE price > ( SELECT AVG(price) FROM product );
Esto establecerá el valor activo en Y para todos los registros que tengan un precio superior al promedio.
La tabla ahora se ve así:
[identificación de la tabla=32 /]
Muestra 2 registros con un valor activo de Y porque están por encima del promedio.
Este tipo de consulta también se puede ejecutar con otros operadores que permiten un solo valor, como
DÓNDE EN Subconsulta
Además, podemos usar una subconsulta con un operador IN en la cláusula WHERE.
Esto es similar al ejemplo anterior que usaba el operador mayor que para un solo valor. El operador IN se puede aplicar a varios valores.
Digamos que la empresa quería actualizar el precio de algunos productos que eran el único artículo de la categoría. Los precios tendrían que reducirse a la mitad.
Nuestra consulta podría verse así:
UPDATE product SET price = price / 2 WHERE category_id IN ( SELECT category_id FROM product GROUP BY category_id HAVING COUNT(*) = 1 );
La subconsulta encuentra todos los valores de category_id donde COUNT es 1. No necesitamos tener COUNT en la parte SELECT de la subconsulta; sin embargo, si lo hacemos, la consulta mostrará un error.
La instrucción UPDATE actualizará el precio cuando la categoría cumpla con los criterios de la subconsulta.
Nuestros resultados se verán así:
[identificación de la tabla=33 /]
Los datos se ven muy similares. Sin embargo, el producto con una ID de categoría de 1 ha actualizado su precio a la mitad de su costo original, porque es el único producto en su categoría.
ACTUALIZAR Subconsulta
Finalmente, puede usar una subconsulta en una instrucción UPDATE para actualizar la tabla.
En los ejemplos anteriores, solo hemos utilizado la tabla de productos. Sin embargo, puede usar una subconsulta en lugar de la tabla de productos, que devolverá un conjunto de resultados que se puede actualizar.
El conjunto de resultados debe ser actualizable, similar al caso cuando crea un objeto VIEW e intenta actualizarlo. Debe ser simple y tener la clave principal.
Por lo tanto, utilizando nuestros ejemplos anteriores, suponga que la empresa quiere cambiar la categoría de todos los productos que están en la categoría 4 a la categoría 5.
Nuestra consulta podría verse así:
UPDATE ( SELECT product_id, category_id FROM product) SET category_id = 5 WHERE category_id = 4;
Es un ejemplo simple que demuestra el concepto. La tabla se reemplazó con la instrucción SELECT que solo muestra dos columnas de la tabla.
Los resultados de esta consulta serían:
[identificación de la tabla=34 /]
Se podría obtener el mismo resultado moviendo la cláusula WHERE a la instrucción UPDATE:
UPDATE ( SELECT product_id, category_id FROM product WHERE category_id = 4) SET category_id = 5;
Conclusión
El uso de una subconsulta en una instrucción UPDATE puede ser una buena manera de mejorar la capacidad de mantenimiento de sus consultas. También puede reducir la cantidad de pasos necesarios para actualizar sus datos al comprimir dos o más consultas en una sola consulta.