Previous | Table of Contents | Next |
Well extend the report to display one column per type. Now, Im not a glutton for punishment and dont particularly like typing. Whenever possible, I like to write programs to do the heavy lifting for me. You can use a SQL statement to generate all of the column expressions automatically like this:
select distinct type + = CASE t.type WHEN + type + THEN s.qty ELSE 0 END, from titles
UNDECIDED = CASE t.type WHEN UNDECIDED THEN s.qty ELSE 0 END, business = CASE t.type WHEN business THEN s.qty ELSE 0 END, mod_cook = CASE t.type WHEN mod_cook THEN s.qty ELSE 0 END, popular_comp = CASE t.type WHEN popular_comp THEN s.qty ELSE 0 END, psychology = CASE t.type WHEN psychology THEN s.qty ELSE 0 END, trad_cook = CASE t.type WHEN trad_cook THEN s.qty ELSE 0 END,
The more data elements you are dealing with, the more likely it is that this approach will be useful for you. Sometimes youll need to try something a couple of times, and it may take a little pruning when its finished, but it sure beats typing it all in!
You can use pairs of single or double quotes freely in SQL Server (just match them correctly). I took advantage of that fact to insert quotes around the value of type after WHEN.
The next step in building the crosstab is to build the raw data from which the totals will be generated. Cut the six case expressions you just generated out of the Result tab and paste them into the Query tab in place of the two (business and non-business) expressions you were using before. You should end up with a query that looks like this:
select t.type, s.qty, UNDECIDED = CASE t.type WHEN UNDECIDED THEN s.qty ELSE 0 END, business = CASE t.type WHEN business THEN s.qty ELSE 0 END, mod_cook = CASE t.type WHEN mod_cook THEN s.qty ELSE 0 END, popular_comp = CASE t.type WHEN popular_comp THEN s.qty ELSE 0 END, psychology = CASE t.type WHEN psychology THEN s.qty ELSE 0 END, trad_cook = CASE t.type WHEN trad_cook THEN s.qty ELSE 0 END from titles t inner join sales s on t.title_id = s.title_id
Go ahead and execute the query.
type qty UNDECIDED business mod_cook popular_comp psychology trad_coo ----------- --- -------- -------- ------- ----------- --------- -------- business 5 0 5 0 0 0 0 business 10 0 10 0 0 0 0 business 25 0 25 0 0 0 0 business 35 0 35 0 0 0 0 business 15 0 15 0 0 0 0 mod_cook 10 0 0 10 0 0 0 mod_cook 25 0 0 35 0 0 0 mod_cook 15 0 0 15 0 0 0 popular_comp 30 0 0 0 30 0 0 popular_comp 50 0 0 0 50 0 0 psychology 20 0 0 0 0 20 0 psychology 3 0 0 0 0 3 0 psychology 75 0 0 0 0 75 0 psychology 10 0 0 0 0 10 0 psychology 20 0 0 0 0 20 0 psychology 25 0 0 0 0 25 0 psychology 15 0 0 0 0 15 0 psychology 25 0 0 0 0 25 0 trad_cook 40 0 0 0 0 0 40 trad_cook 20 0 0 0 0 0 20 trad_cook 20 0 0 0 0 0 20
Im limited to 80 columns, so I had to trim the report a little bit here and there; youre almost done. Each sale is reflected only in the proper column. All we need to do now is show dollar sales instead of unit sales, and total the columns up by stor_id. To show dollar sales, just change the case expression to include s.qty * t.price, like this:
business = CASE t.type WHEN business THEN s.qty * t.price ELSE 0 END,
To total by stor_id, use sum() with GROUP BY.
select s.stor_id, Total = sum(s.qty * t.price), UNDECIDED = sum(CASE t.type WHEN UNDECIDED THEN s.qty * t.price ELSE 0 END), business = sum(CASE t.type WHEN business THEN s.qty * t.price ELSE 0 END), mod_cook = sum(CASE t.type WHEN mod_cook THEN s.qty * t.price ELSE 0 END), popular_comp = sum(CASE t.type WHEN popular_comp THEN s.qty * t.price ELSE 0 END), psychology = sum(CASE t.type WHEN psychology THEN s.qty * t.price ELSE 0 END), trad_cook = sum(CASE t.type WHEN trad_cook THEN s.qty * t.price ELSE 0 END) from titles t inner join sales s on t.title_id = s.title_id group by s.stor_id
stor_id Total UNDECIDED business mod_cook popular_comp psychology trad_coo ------- -------- -------- -------- -------- ---------- --------- -------- 6380 147.86 0.00 99.95 0.00 0.00 47.91 0.00 7066 2,197.75 0.00 0.00 0.00 1,000.00 1,197.75 0.00 7067 1,536.50 0.00 0.00 0.00 0.00 159.70 1,376.80 7131 1,500.55 0.00 0.00 74.75 0.00 1,425.80 0.00 7896 604.40 0.00 404.50 199.90 0.00 0.00 0.00 8042 1,232.00 0.00 498.65 44.85 688.50 0.00 0.00
Mission accomplished. Notice that the SUM() function wraps around the entire case expression. Also, the report is fairly efficient; it requires only a single join of the sales and titles tables (other methods would require one join per column). In addition, my informal tests have shown that the case operator has very little CPU overhead.
Previous | Table of Contents | Next |