Cross-tab Queries with Transact-SQL
The sample procedure sp_transform dynamically generates
a Transact SQL Query that returns a resultset similar to the Cross-Tab Queries in Access or Excel.
Here is a short example (using the database Northwind), that shows how to
use this stored procedure
Prerequisites:
Before you can run this example create the stored procedure sp_transform either in your
master-database or locally in your Northwind database. This demo will run
with Microsoft SQL Server Version 7.0 und Version 2000
Examples
The examples use a crosstab-query to show the total and average amount
of freight costs per year by Employee.
In the first step we create a view, that combines the information from
the orders and the employees table using an INNER JOIN.
CREATE VIEW vFreight AS SELECT lastname, Year(orderdate) as theYear , freight FROM orders o INNER JOIN employees e ON o.employeeid = e.employeeid GO
The result of this view will look similar to the following list:
| lastname | theYear | freight |
| Buchanan | 1996 | 32.38 |
| Suyama | 1996 | 11.61 |
| Peacock | 1996 | 65.83 |
| Leverling | 1996 | 41.34 |
| Peacock | 1996 | 51.30 |
| Leverling | 1996 | 58.17 |
| Peacock | 1996 | 55.09 |
| Peacock | 1996 | 3.05 |
| Callahan | 1996 | 48.29 |
| Dodsworth | 1996 | 146.06 |
| Suyama | 1996 | 3.67 |
| Fuller | 1996 | 55.28 |
| Leverling | 1996 | 25.73 |
| ... | ... | ... | | ... | ... | ... |
The Cross-Tab Query (using sp_transform)
Using this view as a starting point, we will now generate a resultset
that shows the Total freight cost per employee per year.
First example
In the first example we will use lastname as the row-header and
theYear as the column-header, freight is the value field and 'SUM' the
aggregate function:
EXEC sp_transform @TableOrView_name = 'vFreight', @Aggregate_Column = 'freight', @Select_Column = 'lastname', -- row header @pivot_column = 'theYear' -- column header
The result:
| lastname | 1996 | 1997 | 1998 | Total |
| Buchanan | 1365.3700 | 1244.5300 | 1308.8100 | 3918.7100 |
| Callahan | 1326.2800 | 2898.6200 | 3262.9800 | 7487.8800 |
| Davolio | 1967.4800 | 4488.0300 | 2381.1300 | 8836.6400 |
| Dodsworth | 532.8400 | 1046.0900 | 1747.3300 | 3326.2600 |
| Fuller | 1129.1500 | 3690.3000 | 3876.9600 | 8696.4100 |
| King | 664.3200 | 3245.5300 | 2755.5900 | 6665.4400 |
| Leverling | 880.0300 | 6918.3400 | 3086.3700 | 10884.7400 |
| Peacock | 2042.3800 | 6574.8100 | 2728.9500 | 11346.1400 |
| Suyama | 766.1000 | 2114.1700 | 900.2000 | 3780.4700 |
| Total | 10673.9500 | 32220.4200 | 22048.3200 | 64942.6900 |
The second example just shows what the result looks like when you
swap the row-header and column-header fields.
EXEC sp_transform @TableOrView_name = 'vFreight', @Aggregate_Column = 'freight', @Select_Column = 'theyear', -- row header @pivot_column = 'lastname' -- column header
The result:
| theyear | Buchanan | Callahan | Davolio | Dodsworth | Fuller | King | Leverling | Peacock | Suyama | Total |
| 1996 | 1365.3700 | 1326.2800 | 1967.4800 | 532.8400 | 1129.1500 | 664.3200 | 880.0300 | 2042.3800 | 766.1000 | 10673.9500 |
| 1997 | 1244.5300 | 2898.6200 | 4488.0300 | 1046.0900 | 3690.3000 | 3245.5300 | 6918.3400 | 6574.8100 | 2114.1700 | 32220.4200 |
| 1998 | 1308.8100 | 3262.9800 | 2381.1300 | 1747.3300 | 3876.9600 | 2755.5900 | 3086.3700 | 2728.9500 | 900.2000 | 22048.3200 |
| Total | 3918.7100 | 7487.8800 | 8836.6400 | 3326.2600 | 8696.4100 | 6665.4400 | 10884.7400 | 11346.1400 | 3780.4700 | 64942.6900 |
The next example shows the same Query using the AVG-function
EXEC sp_transform @Aggregate_Function = 'AVG', @TableOrView_name = 'vFreight', @Aggregate_Column = 'freight', @Select_Column = 'lastname', -- row header @pivot_column = 'theYear' -- column header
The result:
| lastname | 1996 | 1997 | 1998 | Total |
| Buchanan | 32.5088 | 29.6316 | 31.1621 | 93.3026 |
| Callahan | 12.7526 | 27.8713 | 31.3748 | 71.9988 |
| Davolio | 15.9957 | 36.4880 | 19.3587 | 71.8426 |
| Dodsworth | 12.3916 | 24.3276 | 40.6355 | 77.3548 |
| Fuller | 11.7619 | 38.4406 | 40.3850 | 90.5876 |
| King | 9.2266 | 45.0768 | 38.2720 | 92.5755 |
| Leverling | 6.9293 | 54.4751 | 24.3021 | 85.7066 |
| Peacock | 13.0921 | 42.1462 | 17.4932 | 72.7316 |
| Suyama | 11.4343 | 31.5547 | 13.4358 | 56.4249 |
| Total | 12.8601 | 38.8197 | 26.5642 | 78.2442 |
|