You are on page 1of 27

Module 5:

Working with Subqueries



Module 5: Working with Subqueries
Writing Basic Subqueries
Writing Correlated Subqueries
Comparing Subqueries with Joins and Temporary Tables
Using Common Table Expressions
Lesson 1: Writing Basic Subqueries
What Are Subqueries?
Using Subqueries as Expressions
Using the ANY, ALL, and SOME Operators
Scalar versus Tabular Subqueries
Rules for Writing Subqueries
What Are Subqueries?
Queries nested inside a SELECT, INSERT, UPDATE, or
DELETE statement

Can be used anywhere an Expression is allowed

SELECT ProductID, Name
FROM Production.Product
WHERE Color NOT IN
(SELECT Color
FROM Production.Product
WHERE ProductID = 5)
ProductID Name
--------------------------------------
1 Adjustable Race
2 Bearing Ball
...
(504 row(s) affected)
Result Set:
Example:
Using Subqueries as Expressions
SELECT Name, ListPrice,
(SELECT AVG(ListPrice) FROM Production.Product)
AS Average, ListPrice
(SELECT AVG(ListPrice) FROM Production.Product)
AS Difference
FROM Production.Product
WHERE ProductSubcategoryID = 1
A Subquery can be substituted anywhere an expression can be
used in the following statements, except in an ORDER BY list:
SELECT

UPDATE

INSERT

DELETE

Example:
Name ListPrice Average Difference
---------------------------------------------------------
Mountain-100 Silver, 38 3399.99 438.6662 2961.3238
Mountain-100 Silver, 42 3399.99 438.6662 2961.3238
...
(32 row(s) affected)
Result Set:
Using the ANY, ALL, and SOME Operators
Comparison operators that introduce a subquery can
be modified by the keywords ALL or ANY
SELECT Name
FROM Production.Product
WHERE ListPrice >= ANY
(SELECT MAX (ListPrice)
FROM Production.Product
GROUP BY ProductSubcategoryID)
SOME is an ISO standard equivalent for ANY
SELECT Name
FROM Production.Product
WHERE ListPrice >= ALL
(SELECT MAX (ListPrice)
FROM Production.Product
GROUP BY ProductSubcategoryID)
Name
---------------------
LL Mountain Seat
ML Mountain Seat ...
(304 row(s) affected)
Name
--------------------
Road-150 Red, 62
Road-150 Red, 44...
(5 row(s) affected)
ANY Example:
ALL Example:
Result Sets
Scalar versus Tabular Subqueries
create table T1 (a int, b int)
create table T2 (a int, b int)
select *
from T1
where T1.a > (select max(T2.a)
from T2 where T2.b < T1.b)
A scalar subquery returns a single row of data, while
a tabular subquery returns multiple rows of data
SELECT Name
FROM Production.Product
WHERE ListPrice =
(SELECT ListPrice
FROM Production.Product
WHERE Name = 'Chainring Bolts' )
a b
----------------------
...
(0 row(s) affected)
Name
------------------
Adjustable Race
Bearing Ball ...
(200 row(s) affected)
Scalar Subquery:
Tabular Subquery:
Result Sets

Lesson 2: Writing Correlated Subqueries
What Are Correlated Subqueries?
Building a Correlated Subquery
Using Correlated Subqueries
Using the EXISTS Clause with Correlated Subqueries
What Are Correlated Subqueries?
Outer query passes column
values to the inner query
USE northwind
SELECT orderid, customerid
FROM orders AS or1
WHERE 20 < (SELECT quantity
FROM [order details] AS od
WHERE or1.orderid = od.orderid
AND od.productid = 23)
GO
1
Inner query uses that value
to satisfy the inner query
2
Inner query returns a value
back to the outer query
3
The process is repeated for the
next row of the outer query
4
Back to Step 1
Building a Correlated Subquery
SELECT c.LastName, c.FirstName
FROM Person.Person c JOIN HumanResources.Employee e
ON e.BusinessEntityID = c.BusinessEntityID
WHERE 5000.00 IN
(SELECT Bonus
FROM Sales.SalesPerson sp
WHERE e.BusinessEntityID = sp.BusinessEntityID) ;
SELECT Bonus
FROM Sales.SalesPerson
SELECT c.LastName, c.FirstName
FROM Person.Person c
JOIN HumanResources.Employee e
ON e.BusinessEntityID =
c.BusinessEntityID
Inner Query
Outer Query
Correlated Subquery
+
Using Correlated Subqueries
SELECT DISTINCT c.LastName, c.FirstName
FROM Person.Person c JOIN HumanResources.Employee e
ON e.BusinessEntityID = c.BusinessEntityID
WHERE 5000.00 IN
(SELECT Bonus
FROM Sales.SalesPerson sp
WHERE e.BusinessEntityID = sp.BusinessEntityID);
Example:
LastName FirstName
-----------------------------
Ansman-Wolfe Pamela
Saraive Jos
(2 row(s) affected)
Result Set:
Correlated subqueries are executed repeatedly, once
for each row that may be selected by the outer query
Using the EXISTS Clause with Correlated
Subqueries
SELECT Name
FROM Production.Product
WHERE EXISTS
(SELECT * FROM Production.ProductSubcategory
WHERE ProductSubcategoryID =
Production.Product.ProductSubcategoryID
AND Name = 'Wheels')
When a subquery is introduced with the keyword
EXISTS, the subquery functions as an existence test
Name
------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
...
(14 row(s) affected)
Result Set:
Example:
Lesson 3: Comparing Subqueries with Joins and
Temporary Tables
Subqueries versus Joins
Temporary Tables
Subqueries versus Temporary Tables
Subqueries versus Joins
Joins can yield better performance in some cases where
existence must be checked
Joins are performed faster by SQL Server than subqueries
Subqueries can often be rewritten as joins
SQL Server 2008 query optimizer is intelligent enough to
covert a subquery into a join if it can be done
Subqueries are useful for answering questions that are
too complex to answer with joins
Temporary Tables
Local Temporary Tables:
Have a single number sign (#) as
the first character of their names
Visible only to the current
connection for the user
Deleted when the user disconnects
from SQL Server
Global Temporary Tables:
Have a double number sign (##) as
the first character of their names
Visible to any user once created
Deleted when all users referencing
them disconnect
CREATE TABLE #StoreInfo
(
EmployeeID int,
ManagerID int,
Num int
)
CREATE TABLE ##StoreInfo
(
EmployeeID int,
ManagerID int,
Num int
)
Subqueries versus Temporary Tables
As subqueries get more complex their performance
may decrease
Maintainability can be easier with subqueries in some
situations, and easier with temporary tables in others
Temporary tables can be easier for some to debug
while others prefer to work with a single subquery
Lesson 4: Using Common Table Expressions
What Are Common Table Expressions?
Writing Common Table Expressions
Writing Recursive Queries by Using Common Table
Expressions
What Are Common Table Expressions?
Result set can be used in SELECT, INSERT, UPDATE,
or DELETE
Advantages of common table expressions:
Queries with derived tables become more readable
Provide traversal of recursive hierarchies
WITH TopSales (SalesPersonID, NumSales) AS
( SELECT SalesPersonID, Count(*)
FROM Sales.SalesOrderHeader GROUP BY SalesPersonId )
SELECT * FROM TopSales
WHERE SalesPersonID IS NOT NULL
ORDER BY NumSales DESC
A named temporary result set based on a
SELECT query
Common Table
Expression
Writing Common Table Expressions
Choose a CTE name and column list
1
WITH TopSales (SalesPersonID, NumSales) AS WITH TopSales (SalesPersonID, NumSales) AS
(SELECT SalesPersonID, Count(*)
FROM Sales.SalesOrderHeader GROUP BY SalesPersonId)
Create the CTE SELECT query
2
Use the CTE in a query
3
WITH TopSales (SalesPersonID, NumSales) AS
(SELECT SalesPersonID, Count(*)
FROM Sales.SalesOrderHeader GROUP BY SalesPersonId)

SELECT LoginID, NumSales
FROM HumanResources.Employee e INNER JOIN TopSales
ON TopSales.SalesPersonID = e.EmployeeID
ORDER BY NumSales DESC

WITH TopSales (SalesPersonID, NumSales) AS
( SELECT SalesPersonID, Count(*)
FROM Sales.SalesOrderHeader GROUP BY SalesPersonId )




Ejecucin


SELECT * FROM TopSales
WHERE SalesPersonID IS NOT NULL
ORDER BY NumSales DESC
Writing Recursive Queries by Using Common
Table Expressions
Modify CTE SELECT query when creating CTE:
Create the anchor member query (top of recursion tree)
1
SELECT ManagerID, EmployeeID
FROM HumanResources.Employee
WHERE ManagerID IS NULL

Add the UNION ALL operator
2
SELECT ManagerID, EmployeeID
FROM HumanResources.Employee
WHERE ManagerID IS NULL

UNION ALL
Create the recursive member query that self-references the
CTE
3
SELECT ManagerID, EmployeeID
FROM HumanResources.Employee
WHERE ManagerID IS NULL

UNION ALL

SELECT e.ManagerID, e.EmployeeID
FROM HumanResources.Employee e
INNER JOIN HumanResources.Employee mgr
ON e.ManagerID = mgr.EmployeeID
Demonstration: Using Common Table
Expressions
In this demonstration, you will see how to:
Write a Common Table Expression
Write a Recursive Query
Lab: Working with Subqueries
Exercise 1: Writing Basic Subqueries
Exercise 2: Writing Correlated Subqueries
Exercise 3: Comparing Subqueries with Joins and
Temporary Tables
Exercise 4: Using Common Table Expressions
Logon information
Virtual machine NY-SQL-01
User name Administrator
Password
Pa$$w0rd
Estimated time: 60 minutes
Lab Scenario
You are a database developer at Adventure Works. You have
been asked by several managers of the company to prepare a
number of reports in order to help the executive committee
determine the budget for next year.
Lab Review
How are basic subqueries evaluated?
How are correlated subqueries evaluated?
What could a Common Table Expression be used for?
Module Review and Takeaways
Review Questions
Best Practices

You might also like