SQL - Subconsultas

Una subconsulta o consulta interna o una consulta anidada es una consulta dentro de otra consulta SQL e incrustada dentro de la cláusula WHERE.

Una subconsulta se utiliza para devolver datos que se utilizarán en la consulta principal como condición para restringir aún más los datos que se recuperarán.

Las subconsultas se pueden usar con las instrucciones SELECT, INSERT, UPDATE y DELETE junto con los operadores como =, <,>,> =, <=, IN, BETWEEN, etc.

Hay algunas reglas que las subconsultas deben seguir:

  • Las subconsultas deben ir entre paréntesis.

  • Una subconsulta solo puede tener una columna en la cláusula SELECT, a menos que haya varias columnas en la consulta principal para que la subconsulta compare sus columnas seleccionadas.

  • Un comando ORDER BY no se puede usar en una subconsulta, aunque la consulta principal puede usar un ORDER BY. El comando GROUP BY se puede utilizar para realizar la misma función que ORDER BY en una subconsulta.

  • Las subconsultas que devuelven más de una fila solo se pueden usar con operadores de valor múltiple, como el operador IN.

  • La lista SELECT no puede incluir referencias a valores que se evalúen como BLOB, ARRAY, CLOB o NCLOB.

  • Una subconsulta no puede incluirse inmediatamente en una función establecida.

  • El operador BETWEEN no se puede utilizar con una subconsulta. Sin embargo, el operador BETWEEN se puede utilizar dentro de la subconsulta.

Subconsultas con la instrucción SELECT

Las subconsultas se utilizan con mayor frecuencia con la instrucción SELECT. La sintaxis básica es la siguiente:

SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
   (SELECT column_name [, column_name ]
   FROM table1 [, table2 ]
   [WHERE])

Ejemplo

Considere la tabla CLIENTES que tiene los siguientes registros:

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |  2000.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  8500.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

Ahora, verifiquemos la siguiente subconsulta con una instrucción SELECT.

SQL> SELECT * 
   FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
         FROM CUSTOMERS 
         WHERE SALARY > 4500) ;

Esto produciría el siguiente resultado.

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  5 | Hardik   |  27 | Bhopal  |  8500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+

Subconsultas con la instrucción INSERT

Las subconsultas también se pueden usar con instrucciones INSERT. La instrucción INSERT utiliza los datos devueltos por la subconsulta para insertarlos en otra tabla. Los datos seleccionados en la subconsulta se pueden modificar con cualquiera de las funciones de carácter, fecha o número.

La sintaxis básica es la siguiente.

INSERT INTO table_name [ (column1 [, column2 ]) ]
   SELECT [ *|column1 [, column2 ]
   FROM table1 [, table2 ]
   [ WHERE VALUE OPERATOR ]

Ejemplo

Considere una tabla CUSTOMERS_BKP con una estructura similar a la tabla CUSTOMERS. Ahora, para copiar la tabla CUSTOMERS completa en la tabla CUSTOMERS_BKP, puede usar la siguiente sintaxis.

SQL> INSERT INTO CUSTOMERS_BKP
   SELECT * FROM CUSTOMERS 
   WHERE ID IN (SELECT ID 
   FROM CUSTOMERS) ;

Subconsultas con la instrucción UPDATE

La subconsulta se puede utilizar junto con la instrucción UPDATE. Se pueden actualizar una o varias columnas en una tabla cuando se usa una subconsulta con la instrucción UPDATE.

La sintaxis básica es la siguiente.

UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

Ejemplo

Suponiendo que tenemos la tabla CUSTOMERS_BKP disponible, que es una copia de seguridad de la tabla CUSTOMERS. El siguiente ejemplo actualiza SALARIO 0,25 veces en la tabla CLIENTES para todos los clientes cuya EDAD sea mayor o igual a 27.

SQL> UPDATE CUSTOMERS
   SET SALARY = SALARY * 0.25
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

Esto afectaría a dos filas y finalmente la tabla CLIENTES tendría los siguientes registros.

+----+----------+-----+-----------+----------+
| ID | NAME     | AGE | ADDRESS   | SALARY   |
+----+----------+-----+-----------+----------+
|  1 | Ramesh   |  35 | Ahmedabad |   125.00 |
|  2 | Khilan   |  25 | Delhi     |  1500.00 |
|  3 | kaushik  |  23 | Kota      |  2000.00 |
|  4 | Chaitali |  25 | Mumbai    |  6500.00 |
|  5 | Hardik   |  27 | Bhopal    |  2125.00 |
|  6 | Komal    |  22 | MP        |  4500.00 |
|  7 | Muffy    |  24 | Indore    | 10000.00 |
+----+----------+-----+-----------+----------+

Subconsultas con la instrucción DELETE

La subconsulta se puede usar junto con la instrucción DELETE como con cualquier otra instrucción mencionada anteriormente.

La sintaxis básica es la siguiente.

DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

Ejemplo

Suponiendo que tenemos una tabla CUSTOMERS_BKP disponible que es una copia de seguridad de la tabla CUSTOMERS. El siguiente ejemplo elimina los registros de la tabla CLIENTES para todos los clientes cuya EDAD es mayor o igual a 27.

SQL> DELETE FROM CUSTOMERS
   WHERE AGE IN (SELECT AGE FROM CUSTOMERS_BKP
      WHERE AGE >= 27 );

Esto afectaría a dos filas y finalmente la tabla CUSTOMERS tendría los siguientes registros.

+----+----------+-----+---------+----------+
| ID | NAME     | AGE | ADDRESS | SALARY   |
+----+----------+-----+---------+----------+
|  2 | Khilan   |  25 | Delhi   |  1500.00 |
|  3 | kaushik  |  23 | Kota    |  2000.00 |
|  4 | Chaitali |  25 | Mumbai  |  6500.00 |
|  6 | Komal    |  22 | MP      |  4500.00 |
|  7 | Muffy    |  24 | Indore  | 10000.00 |
+----+----------+-----+---------+----------+