WITH
An introduction to WITH
.
WITH
is a keyword that enables you to form complex queries out of simple named subqueries.
With the way our dataset is structured we can see a lot of information about what’s in the pipeline for sales agents, but we can’t easily see the connection between the managers and the pipeline. However if we create a subquery using WITH
we can run many different queries against it and get information for managers about accounts, deal stages, products, and deal values. The ability to use the results of a query as though it were just another table makes WITH
a powerful tool for querying. For example, if we wanted to know how which managers had the most closed deals and for which accounts, we could run a query like this:
WITH `full pipeline` AS (
SELECT sales_teams.manager,
sales_pipeline.sales_agent,
sales_pipeline.account,
sales_pipeline.product,
sales_pipeline.deal_stage,
sales_teams.regional_office
FROM sales_teams, sales_pipeline
WHERE (sales_pipeline.sales_agent = sales_teams.sales_agent)
)
SELECT manager, regional_office, account,
COUNT(manager)
FROM `full pipeline`
WHERE deal_stage = "Won"
GROUP BY manager, regional_office, account
ORDER BY COUNT(manager) DESC, manager, account
The first several rows of the results table would look like:
manager | regional_office | account | count |
---|---|---|---|
Melvin Marxen | Central | Inity | 44 |
Summer Sewald | West | Singletechno | 42 |
Melvin Marxen | Central | Treequote | 41 |
Summer Sewald | West | Kan-code | 41 |
Melvin Marxen | Central | Warephase | 40 |
Melvin Marxen | Central | Codehow | 39 |
Melvin Marxen | Central | Ron-tech | 39 |
Rocco Neubert | East | Plussunin | 39 |
One restriction on subqueries is that they cannot contain ORDER BY
, LIMIT
, or OFFSET
clauses, but you can still use them in the main query. While you can’t have nested subqueries, you can have multiple named subqueries, and later ones can reference earlier ones. In the following query we are only showing the number of deals per manager from companies that have over 10,000 in revenue:
WITH big_accounts AS (
SELECT account
FROM accounts
WHERE accounts.revenue > 10000
),
pipeline AS (
SELECT sales_teams.manager,
sales_pipeline.sales_agent,
big_accounts.account,
sales_pipeline.deal_stage,
sales_teams.regional_office
FROM sales_teams, sales_pipeline, big_accounts
WHERE sales_pipeline.sales_agent = sales_teams.sales_agent
AND big_accounts.account = sales_pipeline.account
)
SELECT manager,
regional_office,
account,
COUNT(manager)
FROM pipeline
WHERE deal_stage = "Won"
GROUP BY manager, regional_office, account
ORDER BY COUNT(manager) DESC, manager, account
And the results come back as:
manager | regional_office | account | count |
---|---|---|---|
Summer Sewald | West | Kan-code | 41 |
Rocco Neubert | East | Kan-code | 37 |
Cara Losch | East | Kan-code | 23 |
Celia Rouche | West | Kan-code | 14 |
An introduction to inline subqueries.