Skip to main content
Learning DUB

Using Subqueries in SQL

In it's simplest form, a subquery can be described as a query that is nested inside another query, or inside another subquery Subqueries are used to retrieve data from one table based on data in another table.

A subquery is a SELECT query that returns a single value and is nested inside a SELECT, INSERT, UPDATE, or DELETE statement, or inside another subquery. A subquery can be used anywhere an expression is allowed. They generally are used when tables have some kind of relationship. In fact, many SQL statements that include subqueries can be alternatively formulated as joins.

A subquery is also called an inner query or inner select, while the statement containing a subquery is also called an outer query or outer select.

///////////////////////////

Subquery Fundamentals
-- Find the name of the Company Name that placed order 71816. SELECT CompanyName FROM SalesLT.Customer WHERE CustomerID = (SELECT CustomerID FROM SalesLT.SalesOrderHeader WHERE SalesOrderID = 71816); The preceding code returned only one result "Engineered Bike Systems". A subquery can contain any valid SELECT statement, but it must return a single column with the expected number of results. For instance, if a subquery returns only one result, then the main query can check for equality, inequality, greater than, less than, etc. On the other hand, if the subquery returns more than one record, the main query must check to see if a field value is (or is NOT) IN the set of values returned. -- Find the Companies that placed orders between June 2008 and August 2008 SELECT CompanyName FROM SalesLT.Customer WHERE CustomerID IN (SELECT CustomerID FROM SalesLT.SalesOrderHeader WHERE OrderDate BETWEEN '1-June-2008' AND '12-August-2008');

You can also use the Date Format: WHERE OrderDate BETWEEN '2008-06-01' AND '2008-08-12');

//////////////// Ready to use ///////////

Did you know... Many Transact-SQL statements that include subqueries can be alternatively formulated as joins. Below is an example showing both a subquery SELECT and a join SELECT that return the same result set.

/* SELECT statement built using a subquery. */

SELECT Name FROM SalesLT.Product WHERE ListPrice = (SELECT ListPrice FROM SalesLT.Product WHERE Name = 'HL Mountain Frame - Silver, 42')

/* SELECT statement built using a join that returns the same result set. */

SELECT Prd1.Name FROM SalesLT.Product AS Prd1 JOIN SalesLT.Product AS Prd2 ON (Prd1.ListPrice = Prd2.ListPrice) WHERE Prd2.Name = 'HL Mountain Frame - Silver, 42' ////////////Ready to use/////////////// //////////////////////////////////////////
Things you should know about Subqueries in SQL
///

A subquery is subject to a number of restrictions:
The select list of a subquery introduced with a comparison operator can include only one expression or column name (except that EXISTS and IN operate on SELECT * or a list, respectively).
If the WHERE clause of an outer query includes a column name, it must be join-compatible with the column in the subquery select list.
The ntext, text and image data types are not allowed in the select list of subqueries.
Because they must return a single value, subqueries introduced by an unmodified comparison operator (one not followed by the keyword ANY or ALL) cannot include GROUP BY and HAVING clauses.
The DISTINCT keyword cannot be used with subqueries that include GROUP BY.
The COMPUTE and INTO clauses cannot be specified.
ORDER BY can only be specified if TOP is also specified.
A view created with a subquery cannot be updated.
The select list of a subquery introduced with EXISTS by convention consists of an asterisk (*) instead of a single column name. The rules for a subquery introduced with EXISTS are identical to those for a standard select list because a subquery introduced with EXISTS constitutes an existence test and returns TRUE or FALSE rather than data.

Exercise 13: Subqueries 20 to 30 minutes In this exercise, you will practice writing subqueries. 1. Create a report that shows the product name and supplier id for all products supplied by Exotic Liquids, Grandma Kelly’s Homestead, and Tokyo Traders. You will need to escape the apostrophe in “Grandma Kelly’s Homestead.” To do so, place another apostrophe in front of it. For example, SELECT * FROM Suppliers WHERE CompanyName='Grandma Kelly''s Homestead'; 2. Create a report that shows all products by name that are in the Seafood category. 3. Create a report that shows all companies by name that sell products in CategoryID 8. 4. Create a report that shows all companies by name that sell products in the Seafood category. SELECT ProductName, SupplierID FROM Products WHERE SupplierID IN (SELECT SupplierID FROM Suppliers WHERE CompanyName IN ('Exotic Liquids', 'Grandma Kelly''s Homestead', 'Tokyo Traders')); SELECT ProductName FROM Products WHERE CategoryID = (SELECT CategoryID FROM Categories WHERE CategoryName = 'Seafood'); SELECT CompanyName FROM Suppliers WHERE SupplierID IN (SELECT SupplierID FROM Products WHERE CategoryID = 8); SELECT CompanyName FROM Suppliers WHERE SupplierID IN (SELECT SupplierID FROM Products WHERE CategoryID = (SELECT CategoryID FROM Categories WHERE CategoryName = 'Seafood')); //////////////// ///////////////////////Copy Code //////////////////
SQL
SQL
///////////////////////////// ///////////////////////////////////////////
Qualifying Column Names in Subqueries

In the following example, the pub_id column in the WHERE clause of the outer query is implicitly qualified by the table name in the outer query s FROM clause, publishers. The reference to pub_id in the select list of the subquery is qualified by the subquery s FROM clause, that is, by the titles table.

USE pubs SELECT pub_name FROM publishers WHERE pub_id NOT IN (SELECT pub_id FROM titles WHERE type = 'business' ///////////// SELECT Name FROM SalesLT.Product WHERE ProductID NOT IN (SELECT ProductID FROM SalesLT.ProductCategory WHERE Name = 'Bikes') //////////

The general rule is that column names in a statement are implicitly qualified by the table referenced in the FROM clause at the same level.

Here s what the query looks like with these implicit assumptions specified:

USE pubs SELECT pub_name FROM publishers WHERE publishers.pub_id NOT IN (SELECT titles.pub_id FROM titles WHERE type = 'business')

It is never wrong to state the table name explicitly, and it is always possible to override implicit assumptions about table names with explicit qualifications.

/////////////Delete /////////////////

A subquery nested in the outer SELECT statement has the following components:
A regular SELECT query including the regular select list components.
A regular FROM clause including one or more table or view names.
An optional WHERE clause.
An optional GROUP BY clause.
An optional HAVING clause.

/////////////////////// The SELECT query of a subquery is always enclosed in parentheses. It cannot include a COMPUTE or FOR BROWSE clause, and may only include an ORDER BY clause when a TOP clause is also specified. A subquery can be nested inside the WHERE or HAVING clause of an outer SELECT, INSERT, UPDATE, or DELETE statement, or inside another subquery. Up to 32 levels of nesting is possible, although the limit varies based on available memory and the complexity of other expressions in the query. Individual queries may not support nesting up to 32 levels. A subquery can appear anywhere an expression can be used, if it returns a single value. If a table appears only in a subquery and not in the outer query, then columns from that table cannot be included in the output (the select list of the outer query). Statements that include a subquery usually take one of these formats:
WHERE expression [NOT] IN (subquery)
WHERE expression comparison_operator [ANY | ALL] (subquery)
WHERE [NOT] EXISTS (subquery)

There are three basic types of subqueries, those that:
Operate on lists, introduced with IN or those that a comparison operator modified by ANY or ALL.
Are introduced with an unmodified comparison operator and must return a single value.
Are existence tests introduced with EXISTS.

Related Content

Scroll to Top