Introduction
Ok, here is the problem. Suppose we have a table called SalesRecords in a relational database, like the following:
| ID |
Store |
Product |
Sales |
DateTime |
| 1 |
DC |
Apple |
1.23 |
02/03/2002,
07:01:52 |
| 2 |
LA |
Orange |
8.20 |
02/03/2002,
08:31:21 |
| 3 |
NY |
Orange |
0.77 |
02/03/2002,
08:24:33 |
| 4 |
DC |
Watermelon |
3.24 |
02/03/2002,
09:01:24 |
| 5 |
NY |
Strawberry |
6.33 |
02/03/2002,
10:11:35 |
| 6 |
LA |
Pear |
21.45 |
02/03/2002,
10:22:55 |
| 7 |
LA |
Apple |
8.88 |
02/03/2002,
11:50:42 |
| 8 |
DC |
Orange |
13.24 |
02/03/2002,
13:06:17 |
| ... |
... |
... |
... |
... |
What we want, is a summary report showing total sales of a selected group of products at each store. For example, if we select to see the summary for Apple, Orange and Pear only, then the report should look like the following:
| Store |
TotalAppleSales |
TotalOrangeSales |
TotalPearSales |
| DC |
323.50 |
489.20 |
1909.02 |
| LA |
309.42 |
1290.23 |
239.33 |
| NY |
2456.80 |
2301.66 |
780.12 |
| ... |
... |
... |
... |
I will show you how to produce the above result in a single SQL statement. Let's first do this in multiple steps so that you can understand the code easily. First we generate the following result using the SQL statement below. Note that the (case when ... then ... else ... end) expression in the SQL statement generates a new column which is simply a 0-1 indicator, any product that is not among the selected set (Apple, Orange, Pear) will get 0 values in the three generated columns.
select
Store,
(case when Product='Apple' then 1 else 0 end) as IsApple,
(case when Product='Orange' then 1 else 0 end) as IsOrange,
(case when Product='Pear' then 1 else 0 end) as IsPear,
Sales
from
SalesRecords
| Store |
IsApple |
IsOrange |
IsPear |
Sales |
| 1 |
1 |
0 |
0 |
1.23 |
| 2 |
0 |
1 |
0 |
8.20 |
| 3 |
0 |
1 |
0 |
0.77 |
| 4 |
0 |
0 |
0 |
3.24 |
| 5 |
0 |
0 |
0 |
6.33 |
| 6 |
0 |
0 |
1 |
21.45 |
| 7 |
1 |
0 |
0 |
8.88 |
| 8 |
0 |
1 |
0 |
13.24 |
| ... |
... |
... |
... |
... |
Let's assume that the above result was saved in a temporary table ReportTempData. Now we can use the following SQL statement to produce the summary report we wanted.
select
Store,
sum(IsApple*Sales) as TotalAppleSales,
sum(IsOrange*Sales) as TotalOrangeSales,
sum(IsPear*Sales) as TotalPearSales
from
ReportTempData
group by Store
Of course we don't really need the temporary table ReportTempData. Here is the combined single SQL statement that does the job:
select
Store,
sum(A.IsApple*A.Sales) as TotalAppleSales,
sum(A.IsOrange*A.Sales) as TotalOrangeSales,
sum(A.IsPear*A.Sales) as TotalPearSales
from
(
select
Store,
( case when Product='Apple' then 1 else 0 end) as IsApple,
( case when Product='Orange' then 1 else 0 end) as IsOrange,
( case when Product='Pear' then 1 else 0 end) as IsPear,
Sales
from
SalesRecords
) A
group by Store
We can further simplify it to a statement with only one select query:
select
Store,
sum(case when Product='Apple' then Sales else 0 end) as TotalAppleSales,
sum(case when Product='Orange' then Sales else 0 end) as TotalOrangeSales,
sum(case when Product='Pear' then Sales else 0 end) as TotalPearSales
from
SalesRecords
group by Store
That's it. Thanks for reading and please check out my other articles and tools.