Correlated Subqueries with Comparison Operators

To find sales where the quantity is less than the average quantity for sales of that title:

SELECT s1.ord_num, s1.title_id, s1.qty
FROM sales s1
WHERE s1.qty <
    (SELECT AVG(s2.qty)
    FROM sales s2
    WHERE s2.title_id = s1.title_id)
ord_num
title_id
qty

--------
--------
-----

6871
BU1032
5

722a
PS2091
3

D4482
PS2091
10

N914008
PS2091
20

423LL922
MC3021
15





(5 row(s) affected)


The outer query selects the rows of the sales table (that is, of s1) one by one. The subquery calculates the average quantity for each sale being considered for selection in the outer query. For each possible value of s1, SQL Server evaluates the subquery and puts the record being considered in the results if the quantity is less than the calculated average.

Sometimes a correlated subquery mimics a GROUP BY statement. This example finds all titles that have a price greater than the average for books of its type:

SELECT t1.type, t1.title
FROM titles t1
WHERE t1.price >
    (SELECT AVG(t2.price)
    FROM titles t2
    WHERE t1.type = t2.type)
type
title
----
-----------------------------------------------------
business
The Busy Executive's Database Guide
business
Straight Talk About Computers
mod_cook
Silicon Valley Gastronomic Treats
popular_comp
But Is It User Friendly?
psychology
Computer Phobic and Non-Phobic Individuals: 
Behavior Variations
psychology
Prolonged Data Deprivation: Four Case 
Studies
trad_cook
Onions, Leeks, and Garlic: Cooking Secrets 
of the Mediterranean

(7 row(s) affected)

For each possible value of t1, SQL Server evaluates the subquery and includes the row in the results if the price value of that row is greater than the calculated average. It is not necessary to group by type explicitly, because the rows for which average price is calculated are restricted by the WHERE clause in the subquery.