A subquery (also called an inner query or nested query) is an SQL query placed inside another SQL statement. A subquery is most commonly embedded in the WHERE clause of the outer (or main) query and returns data that the main query uses to restrict or compute its result set.
(a,b) IN (SELECT x,y ...)).(a,b) < (SELECT x,y ...) or (a,b) IN (SELECT x,y ...)).Subqueries are most frequently used within SELECT statements. The general form is:
SELECT column_list FROM table_list WHERE column_name operator (SELECT column_list FROM table_list [WHERE ...]);
The sample CUSTOMERS table (columns: ID, NAME, AGE, ADDRESS, SALARY) contains the following rows:
+----+----------+-----+-----------+----------+ | 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 | +----+----------+-----+-----------+----------+
Example query using a subquery with IN:
SELECT * FROM CUSTOMERS WHERE ID IN ( SELECT ID FROM CUSTOMERS WHERE SALARY > 4500 );
Result produced by the above query:
+----+----------+-----+---------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+---------+----------+ | 4 | Chaitali | 25 | Mumbai | 6500.00 | | 5 | Hardik | 27 | Bhopal | 8500.00 | | 7 | Muffy | 24 | Indore | 10000.00 | +----+----------+-----+---------+----------+
Correlated subqueries reference a column from the outer query. They are evaluated once per outer row. Example: find customers whose salary is greater than the average salary of customers from the same address (city):
SELECT c.ID, c.NAME, c.SALARY, c.ADDRESS FROM CUSTOMERS c WHERE c.SALARY > ( SELECT AVG(c2.SALARY) FROM CUSTOMERS c2 WHERE c2.ADDRESS = c.ADDRESS );
This correlated subquery computes the average salary per city for each row of the outer query and returns those outer rows whose salary is above the local average.
A subquery can supply rows to insert into another table. The INSERT INTO ... SELECT form copies query results into a target table.
INSERT INTO table_name [(column1, column2, ...)] SELECT column_list FROM source_tables [WHERE ...];
Example: create a backup copy of the CUSTOMERS table by inserting all rows into CUSTOMERS_BKP (assumed to have compatible columns):
INSERT INTO CUSTOMERS_BKP SELECT * FROM CUSTOMERS WHERE ID IN ( SELECT ID FROM CUSTOMERS );
The inner SELECT in this example is redundant (SELECT * FROM CUSTOMERS could be used directly), but it demonstrates that a subquery can be used to supply the rowset for the INSERT.
Subqueries may be used to determine new values or to select which rows to update.
UPDATE table_name SET column_name = new_value_expression WHERE some_column operator ( SELECT column_name FROM other_table [WHERE ...] );
Example: using CUSTOMERS_BKP (a backup of CUSTOMERS) to update the salaries of customers whose age is greater than or equal to 27. The intent is to set salary to 0.25 times the current value for matching rows.
UPDATE CUSTOMERS SET SALARY = SALARY * 0.25 WHERE AGE IN ( SELECT AGE FROM CUSTOMERS_BKP WHERE AGE >= 27 );
Explanation and effect:
The subquery returns the ages that are ≥ 27 from the backup table. The outer UPDATE updates rows in CUSTOMERS whose AGE matches any of those ages. In the sample data, IDs 1 (AGE 35) and 5 (AGE 27) match; hence their salaries change.
Final state of the CUSTOMERS table after the UPDATE (calculated from original salaries):
+----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 35 | Ahmedabad | 500.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 | +----+----------+-----+-----------+----------+
Subqueries can select which rows to delete:
DELETE FROM table_name WHERE some_column operator ( SELECT column_name FROM other_table [WHERE ...] );
Example: using CUSTOMERS_BKP to delete rows from CUSTOMERS where AGE is ≥ 27:
DELETE FROM CUSTOMERS WHERE AGE IN ( SELECT AGE FROM CUSTOMERS_BKP WHERE AGE >= 27 );
Effect on the sample data: rows with AGE 35 (ID 1) and AGE 27 (ID 5) are removed. The resulting CUSTOMERS table contains the remaining rows:
+----+----------+-----+---------+----------+ | 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 | +----+----------+-----+---------+----------+
Subqueries are a powerful and flexible way to express queries that depend on the results of other queries. Understanding the types (scalar, single-row, multi-row, correlated), the operators that accept subqueries (IN, EXISTS, ANY, ALL), and how to rewrite subqueries as joins or common table expressions helps produce correct, maintainable and performant SQL. Apply the rules and best practices above to design clear and efficient queries.
![]() | Explore Courses for Computer Science Engineering (CSE) exam |
![]() | Get EduRev Notes directly in your Google search |