Crosstab Pivot-table Workbench

Robyn and Phil turn their attention to the bedrock of management reporting, the Pivot Table. Under Phil's 'wild man' influence, they end up with some rather radical ideas.

There comes a time with many Database Developers charged with doing management reports when the process of doing it properly gets very tedious. By ‘doing it properly’, I mean the ‘best practice’ of having to do the basic reporting in SQL and relying on a front-end application to do the presentation. This is particularly true where the management want simple aggregate reports, or ‘Pivot-table’ reports. Presentation is so closely tied with the data that splitting the process can sometimes lead to more problems than it solves. Of course, we have Reporting Services, Analysis Services and other external tools, but there are times when a simple solution based in TSQL has the upper hand.

Anyone who was weaned on Excel knows that these pivot tables are dead simple. You select your data, bang the button and with a bit of dragging and dropping, there it is. Why, they ask, is it so hard to get it out of the database? Why so hard to make changes?

What they want to see is something like this (using NorthWind so those stuck with SQL 2000 can join in)

No. Sales per year

  1996 1997 1998 Total
Margaret Peacock 31 81 44 156
Janet Leverling 18 71 38 127
Nancy Davolio 26 55 42 123
Laura Callahan 19 54 31 104
Andrew Fuller 16 41 39 96
Robert King 11 36 25 72
Michael Suyama 15 33 19 67
Anne Dodsworth 5 19 19 43
Steven Buchanan 11 18 13 42
Sum 152 408 270 830

Now, you’ll notice that we’ve taken a bit of trouble to add some formatting. In the average business, they’re fussy about such things as the alignment of numbers and the clear delineation of totals, and summary lines. It also is easier on the eye. It is therefore handy to format pivot table reports in HTML. We can send them via email them, straight from SQL Server, all in their correct formatting, or put the reports on an intranet and update them daily or hourly. With the contents of this workbench we show you how it is done, and how easy it is to do, all without a .NET programmer in sight!

However, first things first, we must first show you how to do a crosstab, or pivot table in Transact SQL

Crosstabs and Pivot tables

The basic code to do the report is pretty simple.

You’ll notice that the years are hard-coded into the column headings, which are a time bomb waiting to happen. You’ll also realize that the all-important formatting is missing. The structure of the query seems slightly more complicated than necessary, but you’ll see why soon. The PIVOT operator in SQL Server 2005 makes it rather easier but we wanted to make this relevant to the SQL Server 2000 users too

For any sort of portable solution that will work on SQL Server 2000, dynamic SQL is the traditional solution. Basically, the stored procedure generates the tedious code and then executes it. Why, one wonders. This is because there are a number of tweaks that have to be made, such as the order of the columns, and rows. After all, wouldn’t someone want the report ordered by the number of sales of the salesman rather than just alphabetic order? The same basic query may generate a lot of different aggregations. Pretty soon, some sort of automation will be required.

Keith Fletcher contributed to Simple-Talk the ingenious but complex stored procedure that did cross-tabs in his excellent article Creating cross tab queries and pivot tables in SQL. Because we were awed by its grandeur, we didn’t initially want to add our own contribution. However, we had two another objectives, firstly to show how easy the technique can be, and also because we wanted to do more, encouraging you to try things out, and secondly, because we wanted to show how one might mark up the presentation of the crosstab.

Here is a stored procedure that does the trick, along with some examples using NorthWind. (if you are stuck with SQL Server 2000, make the Varchar(MAX)s into Varchar(8000) and don’t be too ambitious with the complexity of your crosstabs!)

You’ll see that this is a developer’s tool. It is easy to crash the procedure by putting in bad SQL. SQL Injectors would love it. No sir, this is a back-office report-generating tool. Let’s try it out:

414-pivot1.jpg

414-pivot2.jpg

HTML Crosstabs

Why bother with this when the Internet abounds with such Cross tab or pivot-table procedures? This is because we are going to take it one stage further so that, instead of just producing a resultset, we want to show how to produce HTML to produce the chart like the one at the beginning of the article.

To reproduce this…

value of orders per quarter

  1st 2nd 3rd 4th Total
USA $81364.94 $50525.40 $58047.56 $55646.73 $245584.63
Germany $66823.20 $64681.22 $42550.91 $56229.29 $230284.62
Austria $32357.82 $37346.79 $17383.60 $40915.63 $128003.84
Brazil $47027.15 $12127.25 $22537.77 $25233.60 $106925.77
France $31085.27 $11225.97 $14407.11 $24639.96 $81358.31
UK $21302.05 $17061.85 $2292.70 $18314.72 $58971.32
Venezuela $21186.40 $11991.60 $12098.75 $11533.89 $56810.64
Sweden $13627.62 $18234.86 $8718.31 $13914.35 $54495.14
Canada $22746.94 $7094.48 $9225.70 $11129.18 $50196.30
Ireland $20500.54 $8291.50 $11376.50 $9811.36 $49979.90
Belgium $19410.67 $3728.48 $7740.70 $2945.00 $33824.85
Denmark $17049.90 $2007.79 $2127.25 $11476.08 $32661.02
Switzerland $4454.02 $10928.70 $7714.06 $8595.88 $31692.66
Mexico $3938.00 $12432.71 $4616.17 $2595.20 $23582.08
Finland $5532.80 $5791.20 $2884.41 $4601.64 $18810.05
Spain $7329.30 $1875.80 $4633.25 $4144.85 $17983.20
Italy $7082.09 $2836.10 $2484.37 $3367.60 $15770.16
Portugal $3335.79 $4311.20 $1519.24 $2306.14 $11472.37
Argentina $6684.10 $716.50 $0.00 $718.50 $8119.10
Norway $3354.40 $822.35 $500.00 $1058.40 $5735.15
Poland $587.50 $1277.60 $808.00 $858.85 $3531.95
Sum $436780.50 $285309.35 $233666.36 $310036.85 $1265793.06

…We need code like this (the first example in the body of the code was used to generate this Pivot-table)…

(n.b this is the SQL Server 2005 version. The SQL Server 2000 version is included with the files you can download at the bottom of the article)

You will have noticed a few things here.

  • The inputs are the same as the first stored procedure, spDynamicCrossTab. This means that you can try out your parameters in SSMS until you have things the way you want them and then you can just move to spDynamicHTMLCrossTab to concentrate on getting the presentation aspects as you want.
  • We have separated the style from the code. All presentation is in an inline style block. This means you can change the way the crosstab looks to your heart’s content.
  • with both stored procedures, you can specify the order of both the columns and rows precisely (it is always nice to have the months, or the days of the week in the correct order!
  • you can specify the units, either before(e.g. ‘£’ or ‘$’) or after (e.g ‘%’) the aggregate values
  • We provide you with an optional output variable so you can take the results and save it easily to a file, using the technique Phil described in his Blog ‘Using BCP to export the contents of MAX datatypes to a file’

You can change the appearance of the crosstab simply by changing the inline style. For example, this …

… will give you this

No. Sales per year

  1996 1997 1998 Total
Margaret Peacock 31 81 44 156
Janet Leverling 18 71 38 127
Nancy Davolio 26 55 42 123
Laura Callahan 19 54 31 104
Andrew Fuller 16 41 39 96
Robert King 11 36 25 72
Michael Suyama 15 33 19 67
Anne Dodsworth 5 19 19 43
Steven Buchanan 11 18 13 42
Sum 152 408 270 830

Lastly, although there is a lot more one can say about these procedures and the tricks one can use, especially with the CSS, here is an illustration of the way one might save the results of your crosstab to an HTML file for your management reporting intranet site. This uses Phil’s technique taken from his blog entry Using BCP to export the contents of MAX datatypes to a file (Phil: Thanks for the plug, Robyn!)

So that’s it. We’ve enjoyed ourselves trying things out, and we’ve been surprised how far we can take the dynamic creation of pivot tables. We suggest you take the workshop and explore the ideas. If you discover anything interesting, we’d love to hear your comments! We’d particularly like to hear of interesting CSS layouts, though displaying them on Simple-Talk will be very difficult.