Click here to Skip to main content
15,893,486 members
Articles / Productivity Apps and Services / Sharepoint

Get Ready to Learn SQL Server 22: Using Subqueries in the FROM Clause

Rate me:
Please Sign up or sign in to vote.
4.67/5 (2 votes)
10 Mar 2015MIT4 min read 6.7K   5  
Subqueries in the FROM clause
This is the fourth in a series of articles about subqueries. In this post, we discuss subqueries in the FROM clause. Other articles discuss their uses in other clauses. All the examples for this lesson are based on Microsoft SQL Server Management Studio and the AdventureWorks2012 database.

Using Subqueries in the FROM Clause

When subqueries are used in the FROM clause, they act as a table that you can use to select columns and join to other tables. Because of this, some people argue they really aren’t subqueries, but derived tables. I like to think of derived tables as a special case of subqueries… subqueries used in the FROM clause!

Regardless of what you call them, there are some unique features derived tables bring to the SQL world that are worth mentioning.

Before we jump into those though, let’s start with the basics, then get familiar with them.

Simple Example

Like all subqueries, those used in the FROM clause to create a derived table are enclosed by parenthesis. Unlike other subqueries though, a derived table must be aliased so that you can reference its results.

In this example, we’re going to select territories and their average bonuses.

SQL
SELECT TerritoryID,
       AverageBonus
FROM   (SELECT   TerritoryID,
                 Avg(Bonus) AS AverageBonus
        FROM     Sales.SalesPerson
        GROUP BY TerritoryID) AS TerritorySummary
ORDER BY AverageBonus

The subquery alias name is TerritorySummary and is highlighted in bold.

When this query run, the subquery is first run and the results created. The results are then used in the FROM clause as if it were a table. When used by themselves, these types of queries aren’t very fascinating; however, when used in combination with other tables, they are.

Let’s add a join to our example above.

SQL
SELECT SP.TerritoryID,
       SP.BusinessEntityID,
       SP.Bonus,
       TerritorySummary.AverageBonus
FROM   (SELECT   TerritoryID,
                 AVG(Bonus) AS AverageBonus
        FROM     Sales.SalesPerson
        GROUP BY TerritoryID) AS TerritorySummary
       INNER JOIN
       Sales.SalesPerson AS SP
       ON SP.TerritoryID = TerritorySummary.TerritoryID

From a data modeling point of view, this query looks like the following:

Derived Table in Join

There is a relationship between the TerritorySummary and the joined table SalesPerson. Of course, TerritorySummary only exists as part of this SQL statement since it is derived.

By using derived tables, we are able to summarize using one set of fields and report on another. In this case, we’re summarizing by TerritoryID but report by each sales person (BusinessEntityID).

You may think you could simply replicate this query using an INNER JOIN, but you can’t as the final GROUP BY for the query would have to include BusinessEntityID, which would then throw-off the Average calculation.

Things You Can Do With Derived Table Subqueries

In many cases, table subqueries can be “flattened.” That is replaced by equivalent joins; however, there are times where a subquery in the FROM clause shines. Here are a couple of examples I thought of.

Derived Tables and Aggregate Functions

When working with aggregate functions, you may have wanted to first summarize some values and then get the overall average. For instance, suppose you want to know the average bonus given for all territories.

If you run:

SQL
SELECT   AVG(SUM(Bonus))
FROM     Sales.SalesPerson
GROUP BY Bonus

You’ll get the following error: Cannot perform an aggregate function on an expression containing an aggregate or a subquery.

You may think you can simply run:

SQL
SELECT AVG(Bonus)
FROM   Sales.SalesPerson

But that calculates the average for bonus for each sales person. To get the average bonus for territories, you first have to calculate the total bonus by territory, and then take the average.

Once way to do this is with derived tables. In the following example, the derived table is used to summarize sales by territory. These are then fed into the Average function to obtain an overall average.

SQL
SELECT AVG(B.TotalBonus)
FROM   (SELECT   TerritoryID,
                 SUM(Bonus) AS TotalBonus
        FROM     Sales.SalesPerson
        GROUP BY TerritoryID) AS B

Joining Derived Tables

You can also join two derived tables together! This can come in handy when you need to aggregate data from two separate tables and combine them together. In the following example, we’re going to do a comparison of Territory Sales to Territory Sales Quotas. We’ll do this by summing sales figures and quotas by Territory.

Here are the two Select statements we’ll use to summarize the sales figures:

SQL
SELECT   TerritoryID,
         SUM(SalesQuota) AS TerritoryQuota
FROM     Sales.SalesPerson
GROUP BY TerritoryID

And:

SQL
SELECT   SOH.TerritoryID,
         SUM(SOH.TotalDue) AS TerritorySales
FROM     Sales.SalesOrderHeader AS SOH
GROUP BY SOH.TerritoryID

To obtain the comparison, we’ll match these two results together by territory ID. By using FROM clause subqueries our SQL to do the comparison is:

SQL
SELECT Quota.TerritoryID,
       Quota.TerritoryQuota,
       Sales.TerritorySales,
       Sales.TerritorySales - Quota.TerritoryQuota
FROM   (SELECT   TerritoryID,
                 SUM(SalesQuota) AS TerritoryQuota
        FROM     Sales.SalesPerson
        GROUP BY TerritoryID) AS Quota
       INNER JOIN
       (SELECT   SOH.TerritoryID,
                 SUM(SOH.TotalDue) AS TerritorySales
        FROM     Sales.SalesOrderHeader AS SOH
        GROUP BY SOH.TerritoryID) AS Sales
       ON Quota.TerritoryID = Sales.TerritoryID

You can see the statement to summarize sales quotas is in bold and the statement summarize actual sales in italics.

Final Comments

In many cases, what you can do with derived tables you can do with joins; however, there are special cases where this isn’t the case. To me, the best explanation is when you need to use two aggregate functions, such as taking the average of a sum.

Keep in mind when writing SQL, it is best to go with the simplest and easiest solution, which in my opinion is usually an INNER JOIN, but not every solution is solved as such. The double aggregation problem is a good example where a derived table shines.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Easy Computer Academy, LLC
United States United States
Hello my name is Kris. I’m here because I am passionate about helping non-techie people to overcome their fear of learning SQL.

I know what it is like to not know where to start or whether the time spent learning is worth the effort. That is why I am here to help you to:
- Get started in an easy to follow step-by-step manner.
- Use your time wisely so you focus on what is important to learn to get the most value from your time.
- Answer your questions. Really! Just post a comment and I’ll respond. I’m here to help.

It wasn’t long ago that I was helping a colleague with some reporting. She didn’t know where to start and soon got overwhelmed and lost as she didn’t know SQL.

I felt really bad, as she was under pressure to get some summary information to her boss, the built-in reports were falling short, and to make them better would require her to know SQL. At that time that seemed impossible! It in dawned on me, it doesn’t have to be that way.

Then I discovered a way for anyone with the desire to easily learn SQL. I worked with my co-worker, started to teach her what I learned and soon she was able to write reports and answer her boss’ questions without getting stressed or ploughing hours into manipulating data in Excel.

It hasn’t always been easy. Sometimes the information seems abstract or too conceptual. In this case I’ve found out that a visual explanation is best. I really like to use diagrams or videos to explain hard-to-grasp ideas.

Having video, pictures, and text really help to reinforce the point and enable learning.

And now I want to help you get the same results.

The first step is simple, click here http://www.essentialsql.com/get-started-with-sql-server/

Comments and Discussions

 
-- There are no messages in this forum --