SideBar    Logical Puzzle
DOWNLOAD THE CODE:
Download the Code 93907.zip

PIVOT Columns Must Be Base Columns
None of PIVOT's columns (grouping, rotation, aggregation) can be directly an expression; rather, they must all be base columns in the table provided to PIVOT as input. It's obvious that the grouping columns are base columns since the grouping columns are derived implicitly. The aggregation column can't be an expression—for example, SUM (Quantity * UnitPrice). You can't even specify COUNT ( *); instead, if you need to use the COUNT aggregate, you must specify a base column name—for example, COUNT (Order-ID). Similarly, you can't specify an expression as the rotation column—for example, YEAR (OrderDate) IN ([1996], [1997], [1998]).

The workaround for all these limitations is to use a table expression similar to using one to circumvent the implicit-grouping problem I described earlier. To demonstrate the technique, suppose that you need to pivot data from the result of a join between the Orders and Order Details tables. You want months on rows, years on columns, and the sum of Quantity * Unit-Price in the intersections of months and years, as Table 2 shows. The code in Listing 5 uses a derived table to provide a solution.

Another simple workaround is to use COUNT(some_column). The column can be either a real column from the input table or a pseudo column in the table expression derived from a constant. For example, the query in Listing 6 returns the output in Table 3 with the count of orders for each month and year.

Can't Rotate More than One Column
The PIVOT operator doesn't let you specify multiple IN clauses to rotate more than one column. For example, you can't request to rotate both shippers and years: FOR ShipVia IN([1], [2], [3]) AND OrderYear IN ([1996],[1997], [1998]).

As a workaround, in the table expression that you're preparing as input to the PIVOT operator, you can concatenate the elements that you want to rotate. For example, to rotate both shippers and years, you can use the expression at callout A in Listing 7 to concatenate the two. In the parentheses following the PIVOT operator (callout B), specify FOR RotationCol IN([1_1996], [1_1997], [1_1998], [2_1996], [2_1997], [2_1998],[3_1996],[3_1997],[3_1998]).The query in Listing 7 calculates the sum of freight for each employee and shipper/year combination, with employees on rows and shipper/year combinations on columns, and generates the output that Table 4 shows.

Can't Specify Multiple Aggregations
PIVOT lets you specify only one aggregation. Suppose you need to get both the sum of freight and count of orders for each employee and shipper, as Web Table 1 (http://www.sqlmag.com, InstantDoc ID 93907) shows. You can't do this directly by using a single PIVOT operation, but as a workaround you can join the result sets of two PIVOT operations, as Listing 8 shows.

The query in Listing 8 defines two CTEs: The SumFreight CTE contains the sum of freight for each employee and shipper, and the CountOrders CTE contains the count of orders for each employee and shipper. The outer query joins SumFreight and Count-Orders based on a match between the employee IDs and returns the columns with the sum of freight and count of orders of each shipper.

Next Time: A More Complete Solution
I've described various limitations of the PIVOT operator and provided workarounds for each limitation. Next time, I'll show you how to write a stored procedure that encapsulates the logic and circumvents most limitations, thereby providing a more complete and flexible solution to dynamic-pivoting needs.

End of Article

Prev. page     1 [2]     next page -->



You must log on before posting a comment.

If you don't have a username & password, please register now.

 
 

ADS BY GOOGLE