19 SQL (Subquery)
19 SQL (Subquery)
(subquery)
A Subquery or Inner query or a Nested query is a query within another SQL query. A subquery is used to
return a column’s value(s) to the main query. A subquery can only return one column. A subquery can
be embedded within HAVING, WHERE or FROM clauses of the main query. A subquery generally consists
of a SELECT statement and can be used with the SELECT, INSERT, UPDATE, and DELETE statements of the
main query.
SELECT column_name(s)
FROM (subquery) as table_alias
WHERE condition;
The result of the subquery will act as the source table for the main query.
SELECT column_name(s)
FROM table_name
WHERE table_column COMPARISON_OPERATOR (subquery);
The rows of the main table will be filtered according to the comparison between the results of the
subquery and the mentioned column of the main table.
SELECT column_name(s)
FROM table_name
WHERE condition
GROUP BY column_name(s)
HAVING group_column COMPARISON_OPERATOR (subquery);
The filtering of the group is done based on the comparison between the results of the subquery and the
mentioned column of the group.
Summary
SQL subquery is a nested inner query enclosed within the main SQL query usually consisting of INSERT,
UPDATE, DELETE and SELECT statements, generally embedded within a WHERE, HAVING and/or FROM
clause along with the expression operators such as =, NOT IN, <, >, >=, <=, IN, EXISTS, BETWEEN, etc.,
used primarily for solving complex cases/problems and increasing the performance or speed of a DBMS
operation. Subqueries can be used as a good alternative to SQL joins as they increase efficiency or speed
of the DBMS operations.
Example: Inserting into table1 particular column value(s) or rows from table2, supposing that the
concerned column(s) from the two tables have similar data types and are in the same order in the
INSERT INTO & SELECT statements.
Example Continued: Suppose that table1 and table2 have similar structure (i.e. same number of
columns with the same data types and in the same order). Now to copy the complete table2 into the
table1, we can use the following syntax.
UPDATE table_name
SET column_name = new_value
WHERE table_column COMPARISON_OPERATOR (subquery: SELECT column_name
FROM table_name
WHERE condition);
Subqueries with the DELETE Statement
Following is the basic syntax.
SELECT column_name(s)
FROM table_name
WHERE table_column COMPARISON_OPERATOR (subquery: SELECT column_name
FROM table_name
WHERE condition);
Note1
Creating a derived table using subqueries and a UNION command. The result-set of the subqueries and
the union command acts as the source of main table in the main query.
Note2: Subqueries
The following subqueries determine the average ordered quantity per customer of each item/product
which is then used in the main query to find the IDs, names and descriptions of the products which
number less than twice their average ordered quantity per order.
We store information particular to products in one table, Products, and information that pertains to
sales orders in another table, SalesOrders. The Products table contains the information about the
various products. The SalesOrders table contains information about customers' orders.
The above query can also be implemented using a JOIN clause, instead of subqueries, as shown below.
Implementing the above problem statement with a JOIN clause makes it possible to obtain a more
detailed result-set (i.e. a result-set with more columns, in turn, giving us more information).
Note3: Subqueries
The following query identifies items/products that are low in stock, while also identifying orders for
those items/products.
SELECT *
FROM SalesOrder
WHERE ProductID IN (SELECT ID
FROM Products
WHERE Quantity < 20)
ORDER BY ShipDate DESC;
In the above example, the subquery makes a list/set of all IDs of the products from the ID column of the
Products table that are less than 20 in number. The subquery then returns the set of values/rows as a
single column to the main query (i.e. to the WHERE clause of the main query). In the WHERE clause of
the main query, the IN keyword tests whether each row in the main query from the SalesOrders table is
a member of the set by comparing the values of the ProdcutID column of the SalesOrders table against
the values of the set. The rows/records are listed in the result-set from the SalesOrders table for all
matching values.
Note that the above query with the subquery is basically doing the work of a query with a JOIN clause.
Note4: Subqueries
Consider two tables in a sample database: FinancialData and FinancialCodes. FinancialData table
contains financial results data. The FinancialCodes table is a table holding the different codes for
financial data and their meaning. To list the revenue items from the FinancialData table, we execute the
following query:
SELECT *
FROM FinancialData
WHERE Code IN (SELECT Code
FROM FinancialCodes
WHERE type = “revenue”);
//OR//
SELECT *
FROM FinancialData
WHERE FinancialData.Code IN (SELECT FinancialCodes.Code
FROM FinancialCodes
WHERE FinancialCodes .type = “revenue” );
The subquery returns all financial codes of type revenue to the WHERE clause of the outer query in
which the returned values are compared with the values of the Code column of the outer table in order
to filter rows from the outer table relating to revenue.
However, the following query lists financial data not relating to revenue.
SELECT *
FROM FinancialData
WHERE FinancialData.Code NOT IN (SELECT FinancialCodes.Code
FROM FinancialCodes
WHERE type = 'revenue' );
Note5: Correlated and uncorrelated subqueries
A subquery can contain a reference to a table defined in a parent statement. This is called an outer
reference. A subquery that contains an outer reference is called a correlated subquery.
For example, the p.ID column in the WHERE clause of the subquery refers to a column in the table
named in the FROM clause of the main query—not the subquery.
The above query extracts the IDs, names and descriptions of the products whose in-stock quantities are
less than double the average ordered quantity per customer/order of that product.
A subquery that does not contain references to tables in a parent statement is called an uncorrelated
subquery. For example, the subquery in the following statement is an uncorrelated subquery.
Similar to the above query, this query extracts the IDs, names and descriptions of the products whose in-
stock quantities are less than double the average ordered quantity per customer/order of that product.
This is a two-step query: first, find the average number of items requested per order; and then compare
it with the available quantity of that product to determine if the product in stock number less than
double that quantity.
The following query is opposite to the above query. The following query determines the products that
have an average in-stock quantity more than double the average quantity by which they have been
ordered per customer.
In the WHERE clause, subqueries help select/filter the rows from the tables listed in the FROM clause of
the outer/parent query.
The ID field of the Products table is a primary key, therefore there is only one record in the Products
table corresponding to any particular product ID.
In the HAVING clause, subqueries help select/filter the group rows, from the group-set specified by the
outer query's GROUP BY clause.
Using a subquery
The following query obtains the same results (as the above one) using a subquery instead of a join:
SELECT SalesOrders.ID,
SalesOrders.OrderDate,
(SELECT CompanyName FROM Customers
WHERE SalesOrders.CustomerID = Customers.ID)
FROM SalesOrders
WHERE OrderDate > '2001/01/01'
ORDER BY OrderDate;
The subquery refers to the CustomerID column in the SalesOrders table even though the SalesOrders
table is not part of the subquery. Instead, the SalesOrders.CustomerID column refers to the SalesOrders
table in the main body of the statement. This is called outer reference and makes the subquery
correlated to the main query.
The WHERE clause in the subquery acts as a matching clause between the columns of the two tables (in
place of the ON matching clause).
A subquery can be used instead of a join whenever only one column is required from the other table.
(Recall that subqueries can only return one column.) In this example, you only needed the
CompanyName column, so the join could be changed into a subquery.
The It's a Hit! company placed no orders, and the subquery returns NULL for this customer.
The above query can also be implemented using JOIN Clause. Companies who have not placed an order
are not listed when inner joins are used, therefore we could specify a right or left outer join to obtain
the above result-set.
SELECT Customers.CompanyName, Customers.State, MAX(SalesOrders.ID )
FROM SalesOrders
RIGHT OUTER JOIN Customers
ON SalesOrders.CustomerID = Customers.ID
WHERE Customers.State = 'WA'
GROUP BY SalesOrders.CustomerID;
Note10
A subquery in the WHERE clause is part of a search condition. Subqueries in the WHERE clause work as
part of the row selection process (i.e. row filtering process). You use a subquery in the WHERE clause
when the criteria you use to select rows depend on the results of another table.
Although we usually use subqueries as search conditions in the WHERE clause, sometimes you can also
use them in the HAVING clause of a query. When a subquery appears in the HAVING clause, like any
expression in the HAVING clause, it is used as part of the group row selection process (i.e. group row
filtering process).
We can use subqueries to join two or more tables data. A subquery can be used to join two or more
tables data where a Parent table has one or more Child relations.
Note11
It is a good practice to set the primary keys and foreign keys in the tables properly in order to get the
correct or properly sequenced result-set.
The above example uses nested subqueries to determine the order IDs of those orders shipped on the
same day as the order date when any item in the fees department was ordered.
The subquery returns the Order Dates corresponding to the fees department which are then compared
with the shipped dates in the WHERE clause of the main query to determine the orders shipped on the
same day as their order dates and thus list their IDs in the result-set.
Note15
The selected data in a subquery can be modified with any of the character, date or number functions.
Note16
A group contains only those columns listed in the SELECT statement. This means that the HAVING clause
can only be applied on the columns listed in the select statement. However, aggregate functions can be
applied to the group in the HAVING clause even if the aggregate column is not listed in the SELECT
statement.
Important Links:
https://www.educba.com/sql-subquery/
https://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sqlanywhere.12.0.1/dbusage/
subqueries-in-having-clause-subquery.html
https://www.tutorialspoint.com/sql/sql-sub-queries.htm
https://www.geeksforgeeks.org/sql-subquery/
Google Search: Subquery in SQL
FROM clause with subquery is SQL
WHERE clause with subquery is SQL
HAVING clause with subquery is SQL
INSERT statement with subqueries in SQL
UPDATE statement with subqueries in SQL
DELETE statement with subqueries in SQL
SELECT statement with subqueries in SQL
Subqueries in SQL
Important rules for Subqueries
1. A subquery is a query within another query. The outer query is called as main query and
inner query is called as subquery.
2. Subqueries must be enclosed within parentheses.
3. A subquery can have only one column in the SELECT clause.
4. The SELECT list cannot include any references to values that evaluate to a BLOB, ARRAY,
CLOB, or NCLOB.
5. You can place the Subquery in a number of SQL clauses: WHERE clause, HAVING clause,
FROM clause.
6. Subqueries can be used with SELECT, UPDATE, INSERT, DELETE statements along with
comparison/expression operators such as IN, Like, =, >, <, and etc.
7. The BETWEEN operator cannot be used with a subquery. However, the BETWEEN operator
can be used within the subquery.
8. Subqueries are on the right side of the comparison operator.
9. The subquery generally executes first when the subquery doesn’t have any co-relation with
the main query, when there is a co-relation the parser takes the decision on the fly on which
query to execute on precedence and uses the output of the subquery accordingly.
10. Subqueries that return more than one row can only be used with multiple value operators
such as the IN operator.
11. An ORDER BY command cannot be used in a subquery, although the main query can use an
ORDER BY. The GROUP BY command can be used to perform the same function as the
ORDER BY in a subquery.
12. A subquery cannot be immediately enclosed in a set function.