{"id":97060,"date":"2023-06-26T19:12:19","date_gmt":"2023-06-26T19:12:19","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=97060"},"modified":"2026-03-17T19:46:43","modified_gmt":"2026-03-17T19:46:43","slug":"using-a-subquery-in-a-select-statement","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/using-a-subquery-in-a-select-statement\/","title":{"rendered":"SQL Subquery in SELECT: Examples &#038; Syntax Guide"},"content":{"rendered":"<p>A subquery in SQL is a SELECT statement embedded inside another SQL statement &#8211; typically within a WHERE, FROM, or SELECT clause. SQL Server supports two types: basic (standalone) subqueries that execute independently, and correlated subqueries that reference columns from the outer query.<\/p>\n<p>Use subqueries in WHERE with comparison operators or IN\/EXISTS for filtering, in FROM as derived tables for intermediate result sets, or in SELECT for computed column values. This guide covers both types with working examples against the AdventureWorks database.<\/p>\n<p style=\"margin: 0in; font-family: Calibri; font-size: 11.0pt;\"><p><strong>This article is part of Greg Larsen's continuing series on Learning T-SQL. To see all the items in the series, <a href=\"https:\/\/www.red-gate.com\/simple-talk\/t-sql-coding-basics\/\">click here<\/a>.<\/strong><\/p>\n<\/p>\n<p>Did you know you can include a <code>SELECT<\/code> statement within another <code>SELECT<\/code> statement? When a <code>SELECT<\/code> statement is embedded within another statement it is known as a subquery. There are two types of subqueries: basic subquery and correlated subquery.<\/p>\n<p>In this article I will be discussing both types of subqueries and will be providing examples of how to use a subquery in different places within in a <code>SELECT<\/code> statement.<\/p>\n<h2>Difference between a basic subquery and a correlated subquery<\/h2>\n<p>A basic subquery is a \u201cstand alone\u201d <code>SELECT<\/code> statement that is embedded inside another SQL statement. By \u201cstand alone\u201d, I mean the <code>SELECT<\/code> statement that is embedded in another statement can be run independently from the statement in which it is embedded. A correlated subquery on the other hand is also a <code>SELECT<\/code> statement embedded within another query that has a dependence on the statement in which it is embedded. The correlated subquery cannot be run independently from the statement it is embedded because of the dependency.<\/p>\n<p>A subquery and correlated subquery can be used anywhere in a SQL command that an expression can be used. Both types of subqueries are also known as an \u201cinner query\u201d or \u201cinner select\u201d. Whereas the SQL statement that contains the embedded subquery is known as the outer query. Subqueries are easy to spot because they are contained within a set of parentheses.<\/p>\n<p>Depending on how the inner query is used in relationship to the outer query, will determine how many columns and values a subquery can return. For example, when a subquery is used in a <code>WHERE<\/code> cause that contains a comparison operator (<code>=<\/code>, <code>!=<\/code>, <code>&lt;<\/code>, <code>&gt;<\/code>, or <code>&gt;=<\/code>) the subquery needs to return a single column value.<\/p>\n<p>If the subquery is used with a comparison operator that supports multiple values, like an <code>IN<\/code> expression, then the subquery can return multiple values. A subquery can also return multiple columns when used in an <code>EXISTS<\/code> expression or when used in a derived table in the <code>FROM<\/code> clause.<\/p>\n<p>To better understand how to use these two different types of subqueries in a <code>SELECT<\/code> statement let me go through a few subquery examples in the following sections.<\/p>\n<p><strong>Read also:\u00a0<br \/><\/strong><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/introduction-to-gaps-and-islands-analysis\/\">Gaps and islands analysis in SQL<\/a><strong><br \/><\/strong><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/exploring-the-sql-server-choose-function\/\">CHOOSE function in SQL Server<\/a><\/p>\n<h2>Test data<\/h2>\n<p>All the examples in this article will run against that <em>AdventureWorks2019 OLTP <\/em>sample database. If you want to follow along and run the examples in this article you will need to download and restore the backup file for <em>AdventureWorks2019 <\/em>databases. The download link for this backup can be found on this <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/samples\/adventureworks-install-configure?view=sql-server-ver16&amp;tabs=ssms\">web page<\/a>, or by downloading using this <a href=\"https:\/\/github.com\/Microsoft\/sql-server-samples\/releases\/download\/adventureworks\/AdventureWorks2019.bak\">link<\/a>.<\/p>\n<h2>Ways to use subqueries<\/h2>\n<p>In the following sections, I will demonstrate several ways to use a subquery to create richer queries that I have demonstrated before. Subqueries let you have dynamic, data-driven queries where instead of a literal value (or list of values), you can dynamically get a value or list of values from a query.<\/p>\n<h3>Using a subquery in a column list<\/h3>\n<p>Both types of subqueries can be used in a column list. When a basic or correlated subquery is used in a column list it can only return a single value. The value returned will be incorporated into the result set as a column value in the outer query. To see basic subquery in a column list in action consider the code in Listing 1.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT TerritoryID FROM Sales.Customer\n        WHERE CustomerID = 29974;<\/pre>\n<p><strong>Listing 1: Code to return a <em>TerritoryID <\/em> <\/strong><\/p>\n<p>The code in Listing 1 will return a <code>TerritoryID<\/code> for <code>CustomerID = 29964<\/code>. This query will be used as a subquery in Listing 2.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019; \nGO \nSELECT CustomerID,\n       DueDate,        \n       TotalDue,        \n       (SELECT TerritoryID \n        FROM Sales.Customer         \n        WHERE CustomerID = 29974) AS TerritoryID \nFROM Sales.SalesOrderHeader \nWHERE CustomerID = 29974;<\/pre>\n<p><strong>Listing 2: Using a subquery in a column list<\/strong><\/p>\n<p>By Reviewing the code in Listing 2 you can see the code from Listing 1 is embedded in the column list. In Listing 2 the first three column values <code>CustomerID<\/code><em>, <\/em><code>DueDate<\/code><em> and <\/em><code>TotalDue<\/code> are returned from the <code>Sales.SalesOrderHeader<\/code> table. But the 4<sup>th<\/sup> column returned is from the results of the subquery. Or in this case the <code>TerritoryID<\/code> from the <code>Sales.Customer<\/code> table.<\/p>\n<p>When the code in Listing 2 is executed the results in Report 1 are produced.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"493\" height=\"143\" class=\"wp-image-97061\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-1.png\" \/><\/p>\n<p><strong>Report 1: Results when Listing 2 is run<\/strong><\/p>\n<p>The subquery that returns the <code>TerritoryID<\/code> column value is only evaluated one time, and the values returned from the subquery are then placed on every row returned from the outer query. Additionally worth mentioning is the basic subquery code can be run independently of the code in which it is embedded. Since this code can be run independently it make this embedded <code>SELECT<\/code> statement a basic subquery, and not a correlated subquery.<\/p>\n<p>A correlated subquery can also be included in a column list. To demonstrate this, refer to Listing 3.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT TOP 5 C.CustomerID, \n       (SELECT SUM(TotalDue) FROM Sales.SalesOrderHeader H\n        WHERE H.CustomerID = C.CustomerID) AS TotalDue\nFROM Sales.Customer C\nORDER BY TotalDue DESC;<\/pre>\n<p><strong>Listing 3: Correlated subquery in selection list<\/strong><\/p>\n<p>When the code is Listing 3 is executed the results in Report 2 is displayed.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"211\" height=\"146\" class=\"wp-image-97062\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-2.png\" \/><\/p>\n<p><strong>Report 2: Results when Listing 3 is run <\/strong><\/p>\n<p>The difference between a basic subquery and a correlated subquery is the correlate subquery references columns from the outer query. In Listing 3 the correlated subquery referenced the column <code>C.CustomerID<\/code>. The correlated subquery is run once for every row returned from the outer query. The correlated subquery calculates the total amount due for each customer selected. Another difference between a basic query and a correlated subquery is the correlated subquery cannot be run independently of the outer query without getting an error.<\/p>\n<p>When a subquery or correlated subquery is used in the column list the embedded code can only bring back a single column and a single column value. If you try to return multiple columns, or multiple values an error will occur.<\/p>\n<p>To show what will happen when multiple columns are requested in a subquery within a column list, I will run the code in Listing 4.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT CustomerID,\n       DueDate,\n       TotalDue,\n       (SELECT TerritoryID, StoreID FROM Sales.Customer\n        WHERE CustomerID = 29974) AS TerritoryID\nFROM Sales.SalesOrderHeader\nWHERE CustomerID = 29974;<\/pre>\n<p><strong>Listing 4: Trying to bring back multiple column values in subquery code <\/strong><\/p>\n<p>In the subquery in Listing 4, the <code>StoreID<\/code> column was added to the subquery. When this code is executed the error in Report 3 is produced.<\/p>\n<p><code>Msg 116, Level 16, State 1, Line 7<\/code><br \/><code>Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.<\/code><\/p>\n<p><strong>Report 3: Error when more than one column is identified in a column list subquery. <\/strong><\/p>\n<p>In order to bring back the <code>StoreID<\/code> value a second subquery can be added to the original code, as was done in Listing 5.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT CustomerID,\n       DueDate,\n       TotalDue,\n       (SELECT TerritoryID FROM Sales.Customer\n        WHERE CustomerID = 29974) AS TerritoryID,\n       (SELECT StoreID FROM Sales.Customer\n        WHERE CustomerID = 29974) AS StoreID\nFROM Sales.SalesOrderHeader\nWHERE CustomerID = 29974;<\/pre>\n<p><strong>Listing 5: Having multiple subqueries in a column list.<\/strong><\/p>\n<p>I\u2019ll leave it up to you to verify that both the <code>TerritoryID<\/code> and <code>StoreID<\/code> values are returned using the two different subqueries in Listing 5.<\/p>\n<h3>Using a Subquery in a WHERE clause<\/h3>\n<p>A basic and correlated subquery can also be used in a <code>WHERE<\/code> statement. Depending on the operators used in the <code>WHERE<\/code> constraint will determine the number of values a subquery can return. If the subquery uses one of these operators: &#8220;<code>=<\/code>, <code>!=<\/code>, <code>&lt;<\/code>, <code>&gt;<\/code>, or <code>&gt;=\"<\/code> then only a single value can be returned from the subquery in the <code>WHERE<\/code> constraint. To show an example of using a basic subquery in the <code>WHERE<\/code> constraint that uses one of these operators review the code in Listing 6.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT TOP 5 CustomerID, TerritoryID, TotalDue \nFROM  Sales.SalesOrderHeader\nWHERE TerritoryID = (SELECT TerritoryID \n                     FROM Sales.SalesTerritory \n                     WHERE Name = 'Northeast');<\/pre>\n<p><strong>Listing 6: Using a subquery in the WHERE constraint. <\/strong><\/p>\n<p>In Listing 6 the subquery code is associated with the <code>WHERE<\/code> constraint. In this case the subquery returns the <code>TerritoryID<\/code> for the \u201cNortheast\u201d region. The <code>TerritoryID<\/code> returned is then used in conjunction the equals (\u201c<code>=<\/code>\u201d) operator. When the code in Listing 6 is executed, it produces the output in Report 4.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"289\" height=\"148\" class=\"wp-image-97063\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-3.png\" \/><\/p>\n<p><strong>Report 4: Output when Listing 5 is executed.<\/strong><\/p>\n<p>The operator used in the <code>WHERE<\/code> constraint in the prior example can return a single value because the operator \u201c<code>=<\/code>\u201d was used. But when an operator used in conjunction with the subquery can handle multiple values, then a subquery can bring back more than a single value. To show how multiple values can be used in a correlated subquery the \u201cIN\u201d operator will be used in the subquery in Listing 6.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT TOP 5 CustomerID, TerritoryID, TotalDue \nFROM Sales.SalesOrderHeader\nWHERE TerritoryID IN (SELECT TerritoryID \n                     FROM Sales.SalesTerritory \n                     WHERE Name Like '%east');<\/pre>\n<p><strong>Listing 6: Using a correlated subquery with the IN operator<\/strong><\/p>\n<p>The subquery in listing 6 returns multiple <em>TerritoryID<\/em> values. Multiple values can be returned because the IN operator supports multiple values. When the code in Listing 6 is executed the results in Report 4 is produced.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"296\" height=\"150\" class=\"wp-image-97064\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-4.png\" \/><\/p>\n<p><strong>Report 4: Output produced when the in operator is used.<\/strong><\/p>\n<p>Here you can see <code>TerritoryID<\/code> values of 2 and 5 were returned from the subquery, but since it is not a correlated subquery, you can also simply execute the code in the <code>IN<\/code> expression, something I frequently do by just highlighting the code in SSMS:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"790\" height=\"110\" class=\"wp-image-97065\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/a-picture-containing-text-screenshot-font-line.png\" alt=\"A picture containing text, screenshot, font, line\n\nDescription automatically generated\" \/> <br \/>The output of this code will be the <code>TerritoryID<\/code> values, which are, as expected, 2 and 5.<\/p>\n<h3>Using a Subquery in a FROM clause<\/h3>\n<p>A subquery can also be used in a <code>FROM<\/code> clause. When a subquery is used in a <code>FROM<\/code> clause the set created by the subquery is commonly called a <strong>derived<\/strong> table, which is stored in memory. In Listing 7 I have used a subquery to return a subset of the <code>SalesOrderHeader<\/code> rows for a specific date. The derived table is then joined with the <code>SalesOrderDetail<\/code><em>, <\/em>and the <code>Production.Product<\/code> table to build the final result set.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO \nSELECT Header.SalesOrderID, \n       Header.OrderDate,  \n       Name, \n       StandardCost \nFROM \n   (SELECT SalesOrderID, \n           OrderDate\n    FROM Sales.SalesOrderHeader \n    WHERE OrderDate = '2012-08-21 00:00:00.000') AS Header\n     JOIN Sales.SalesOrderDetail AS Detail\n       ON Header.SalesOrderID = Detail.SalesOrderID\n     JOIN Production.Product AS Product\n       ON Detail.ProductID = Product.ProductID;<\/pre>\n<p><strong>Listing 7: Subquery in the FROM clause<\/strong><\/p>\n<p>When the <code>SELECT<\/code> statement in Listing 7 is execute the results in Report 5 are produced.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"604\" height=\"155\" class=\"wp-image-97066\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-6.png\" \/><\/p>\n<p><strong>Report 5: Results when Listing 7 is executed.<\/strong><\/p>\n<p>The <code>SalesOrderID<\/code> and <code>OrderDate<\/code> are the columns that came from the subquery. Writing a subquery that is used in a <code>FROM<\/code> clause should be avoid if there is another way to write the query. This is because there are no indexes on a derived table so performance might suffer.<\/p>\n<p>A correlated subquery cannot be used in a <code>FROM<\/code> clause. The reason is because the correlated subquery cannot be evaluated for every row of the outer query.<\/p>\n<h3>Using a Subquery in a HAVING clause<\/h3>\n<p>A subquery can also be used in a <code>HAVING<\/code> clause. To show how a subquery can be used in a <code>HAVING<\/code> clause let\u2019s first consider the <code>SELECT<\/code> statement in Listing 8.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT COUNT(*) AS NumOfOrders\n        FROM [Sales].[SalesOrderHeader]\n        WHERE OrderDate = '2014-05-01 00:00:00.000';<\/pre>\n<p><strong>Listing 8: Number of orders created for a specific date<\/strong><\/p>\n<p>The <code>SELECT<\/code> statement in Listing 8 identifies the orders that were created on May 1, 2014, which in this case where 227 orders created on that date. Suppose now you want to identify which <code>OrderDates<\/code> have more orders than the number of orders created on May 1, 2014 (which is 227). To do that you could take the query in Listing 8 and place it in the <code>HAVING<\/code> clause as a subquery, as I have done in Listing 9.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT COUNT(*) AS NumOfOrders, OrderDate \nFROM [Sales].[SalesOrderHeader]\nGROUP BY OrderDate\nHAVING COUNT(*) &gt;\n       (SELECT COUNT(*) AS NumOfOrders\n        FROM [Sales].[SalesOrderHeader]\n        WHERE OrderDate = '2014-05-01 00:00:00.000')\nORDER BY OrderDate;<\/pre>\n<p><strong>Listing 9: Using a subquery in a HAVING clause<\/strong><\/p>\n<p>When Listing 9 is run the results are shown in Report 6<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"307\" height=\"171\" class=\"wp-image-97067\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-7.png\" \/><\/p>\n<p><strong>Report 6: Results when Listing 9 is executed.<\/strong><\/p>\n<p>By reviewing Report 6 you can see that there are 6 <code>OrderDate <\/code>values that have processed more orders than on May 1, 2014.<\/p>\n<p>A correlated subquery can also be used in a <code>HAVING<\/code> clause. To demonstrate this, suppose you want to return the <code>SalesOrderID<\/code> values in the <code>Sales.SalesOrderHeader<\/code> table that have more than 70 detailed records. The code in Listing 10 accomplishes this by using a correlated subquery in the <code>HAVING<\/code> clause.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019\nGO\nSELECT H.SalesOrderID \nFROM Sales.SalesOrderHeader AS H\nGROUP BY SalesOrderID\n-- Having more that 70 detail rows\nHAVING (SELECT COUNT(*) \n        FROM Sales.SalesOrderDetail AS D\n        WHERE H.SalesOrderID = D.SalesOrderID) &gt; 70;<\/pre>\n<p><strong>Listing 10: Correlated subquery in HAVING clause.<\/strong><\/p>\n<p>When the code in Listing 10 is run the four rows in Report 7 were found.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"109\" height=\"132\" class=\"wp-image-97068\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-8.png\" \/><\/p>\n<p><strong>Report 7: The results when the code in Listing 10 is executed. <\/strong><\/p>\n<h3>Using a subquery in a Function call<\/h3>\n<p>A subquery can also be used as a parameter of a function call. The code in Listing 11 shows how a subquery can be used as a parameter to the <code>DATEDIFF<\/code> function.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\nSELECT TOP 3 SalesOrderID,\n             CustomerID,\n             OrderDate,\n             DATEDIFF\n               (dd,\n                OrderDate, \n                (SELECT Max(OrderDate) \n                 FROM Sales.SalesOrderHeader \n                 WHERE CustomerID = 29610)\n                ) NumOfDays\nFROM Sales.SalesOrderHeader\nWHERE CustomerID = 29610;<\/pre>\n<p><strong>Listing 11: Using a subquery in a function call<\/strong><\/p>\n<p>In Listing 11 the subquery determines the maximum order date for <code>CustomerID = 29610<\/code>. Which in this case is 2013-02-08. The <code>DATEDIFF<\/code> function then determines the number of days between that date and other orders for <code>CustomerID<\/code> 29610, and only returns the <code>TOP<\/code> three orders. When the code in Listing 11 is executed, the results are shown in Report 8.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-97069\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-9.png\" width=\"591\" height=\"111\" \/><\/p>\n<p><strong>Report 8: Results when Listing 10 is executed<\/strong><\/p>\n<p>Which in this case are the oldest three orders for <code>CustomerID<\/code> 29610.<\/p>\n<h2>Performance Considerations for Basic Subqueries<\/h2>\n<p>In the Microsoft documentation about subqueries found <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/performance\/subqueries?view=sql-server-ver16\">here<\/a>, the following statement regarding performance is mentioned:<\/p>\n<p><em>In Transact-SQL, there&#8217;s usually no performance difference between a statement that includes a subquery and a semantically equivalent version that doesn&#8217;t<\/em>.<\/p>\n<p>To validate that a subquery performs the same as an equivalent version that doesn\u2019t use a subquery let\u2019s review the code in Listing 12.<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">USE AdventureWorks2019;\nGO\n-- Subqeury\nSELECT OD.*  FROM Sales.SalesOrderDetail AS OD\nWHERE ProductID = (SELECT ProductID \n                   FROM Production.Product\n                WHERE Name = 'AWC Logo Cap'); \nGO\n-- Join query \nSELECT OD.*\nFROM Sales.SalesOrderDetail AS OD\nINNER JOIN \nProduction.Product AS P\nON OD.ProductID = P.ProductID\nWHERE P.Name = 'AWC Logo Cap';\nGO<\/pre>\n<p><strong>Listing 12: Two different but similar SELECT queries<\/strong><\/p>\n<p>In Listing 12 there are two different <code>SELECT<\/code> statements. The first <code>SELECT<\/code> statement uses a subquery to identify which <code>Sales.SalesOrderDetail<\/code> records to return. The second <code>SELECT<\/code> query returns uses a <code>JOIN<\/code> to identify the same set of <code>Sales.SalesOrderDetail<\/code> records. Both queries are equivalent. Meaning they have the same execution plan and return the same set of records.<\/p>\n<p>Figure 1 show the actual execution plan for the first query, the <code>SELECT<\/code> statement with the subquery. Whereas Figure 2 shows the execution plan for the <code>SELECT<\/code> statement that uses the JOIN logic.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1456\" height=\"561\" class=\"wp-image-97070\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-10.png\" \/><\/p>\n<h1><strong>Figure 1: Actual execution plan for SELECT statement that contains the subquery<\/strong><\/h1>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1505\" height=\"557\" class=\"wp-image-97071\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2023\/06\/word-image-97060-11.png\" \/><\/p>\n<p><strong>Figure 2: Actual execution plan for the SELECT statement<\/strong><\/p>\n<p>By reviewing both execution plans you can see that other than the text of the query, the plans are both exactly the same. It should be noted that as your queries grow more and more complex there is a breaking point where it is too costly to find the perfect plan.<\/p>\n<h1>Performance Issues when using correlated subqueries<\/h1>\n<p>When using a correlated subquery you need to worry about the number of rows in the outer query. When the outer query contains a small number of rows a correlated subquery doesn\u2019t perform too bad. But as volume of rows in the outer query gets larger you will find a correlated subquery start to have performance issues.<\/p>\n<p>This is because the inner query (correlated subquery) has to be evaluated for every row in the outer query. Keep this scale issue in mind when you are testing out correlated subqueries. Make sure you test your code against production size tables prior to promoting a code with a correlated subquery to into your production environment.<\/p>\n<p>Keep in mind that as rowcounts increase, complexity can be a concern as well. For example, you can next subqueries many levels deeps such as:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT &lt;Columns&gt;\nFROM    Table1\nWHERE  ColumnName IN \n            (SELECT ColumnName\n             FROM    Table2\n             WHERE  EXISTS (SELECT *\n                            FROM Table3\n                            WHERE Name IN (\n                                   SELECT Name\n                                   FROM   Table4\u2026<\/pre>\n<p>This may be necessary to answer a question your users have, but at a certain point a query with too many subqueries can become complex to optimize and execute reasonably. In some cases, it may be useful to break your queries up and use <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/t-sql-programming-sql-server\/temporary-tables-in-sql-server\/\">temporary tables<\/a> to capture rows to eliminate some subqueries.<\/p>\n<h1>Using a subquery in a SELECT statement<\/h1>\n<p>A subquery is a <code>SELECT<\/code> statement that is embedded in another SQL statement. A subquery can be a stand-alone <code>SELECT<\/code> statement (meaning it can be run independently of the outer query) or it can be a correlated <code>SELECT<\/code> statement (meaning it cannot be run independently of the outer query).<\/p>\n<p>Depending on the operator in which a subquery or correlated subquery is used with, the subquery might only be allowed to return a single value or more than one value, and\/or column. Subquery performance is typically the same as an equivalent query that uses a <code>JOIN<\/code>. In this article I only showed how to use subqueries in a <code>SELECT<\/code> statement. but subqueries can also be used in other statements like <code>INSERT<\/code>, <code>UPDATE<\/code> and <code>DELETE<\/code>.<\/p>\n\n\n<section id=\"my-first-block-block_1d20807842f8bc4fa6f94ae84a175cff\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Fast, reliable and consistent SQL Server development&#8230;<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            &#8230;with SQL Toolbelt Essentials. 10 ingeniously simple tools for accelerating development, reducing risk, and standardizing workflows.                                    <\/div>\n            <\/div>\n                            <a href=\"https:\/\/www.red-gate.com\/products\/sql-toolbelt-essentials\/\" class=\"btn btn--secondary btn--lg\">Learn more &amp; try for free<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs: How to use a subquery in a SELECT statement in SQL Server<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. What is the difference between a subquery and a correlated subquery?<\/h3>\n            <div class=\"faq-answer\">\n                <p>A basic subquery is a standalone SELECT that can execute independently of the outer query. A correlated subquery references one or more columns from the outer query, so it executes once for each row processed by the outer statement. Correlated subqueries are more flexible but can be slower on large datasets because of the row-by-row execution pattern.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. Can you use a subquery in a SELECT clause in SQL Server?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Yes. A scalar subquery in the SELECT clause returns a single value for each row of the outer query. For example, SELECT ProductName, (SELECT AVG(Price) FROM Products) AS AvgPrice FROM Products computes the average alongside each row. The subquery must return exactly one column and one value, or SQL Server raises an error.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. When should you use EXISTS vs. IN with a subquery?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Use EXISTS when you only need to check whether matching rows exist &#8211; it stops processing as soon as it finds the first match, making it faster for large datasets. Use IN when the subquery returns a small, distinct set of values to compare against. EXISTS handles NULLs more predictably than IN, which can produce unexpected results when the subquery contains NULL values.<\/p>\n            <\/div>\n            <\/section>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to use subqueries in SQL SELECT statements with practical examples. Covers basic subqueries, correlated subqueries, EXISTS, IN, and derived tables in SQL Server.&hellip;<\/p>\n","protected":false},"author":78478,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,143525,143531],"tags":[],"coauthors":[11330],"class_list":["post-97060","post","type-post","status-publish","format-standard","hentry","category-featured","category-learn","category-t-sql-programming-sql-server"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/97060","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/78478"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=97060"}],"version-history":[{"count":10,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/97060\/revisions"}],"predecessor-version":[{"id":109252,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/97060\/revisions\/109252"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=97060"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=97060"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=97060"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=97060"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}