Welcome Guest!
Create Account | Login
Locator+ Code:

Search:
FTPOnline
Channels Conferences Resources Hot Topics Partner Sites Magazines About FTP RSS 2.0 Feed

Free Trial Issue of Visual Studio Magazine

Take Advantage of New T-SQL Features (Continued)

Implement Pivots in T-SQL
Developers upsizing from Jet to SQL Server databases have complained long and loud about T-SQL's lack of PIVOT and TRANSFORM keywords for writing crosstab queries. SQL Server 2005 finally implements PIVOT, but not TRANSFORM. PIVOT requires a FOR operator and an IN predicate that contains the equivalent of Jet's fixed column headings. The FOR operator doesn't support an expression as the PIVOT argument. Here's the generic PIVOT operator syntax:

SELECT RowHeader1, RowHeader2, ... 
   ColValue1 AS ColHeader1, 
   ColValue2 AS ColHeader2, 
   ColValue3 AS ColHeader3, ...
FROM TableName
PIVOT (Aggregate(ValueColName) 
   FOR ValueSourceColName 
   IN(ColValue1, ColValue2, ColValue3, ...))

The OrdersByProduct1997.sql sample T-SQL script creates a rollup table from the Northwind database's online transaction processing (OLTP) records. The OrdersByProduct1997 source table has these columns: CategoryName (nvarchar(20)), ProductName (nvarchar(40)), Quarter (int), and ProductOrders (money) (see Figure 1). A PIVOT expression (OrdersByProduct1997Pivot.sql) returns a crosstab rowset with columns that report quarterly and annual sales for 1997 (see Figure 2):

IF OBJECT_ID (N'OrdersByProduct1997Pivot', N'U') 
   IS NOT NULL 
   DROP TABLE dbo.OrdersByProduct1997Pivot 
GO
CREATE TABLE dbo.OrdersByProduct1997Pivot 
   (Category nvarchar(20), Product nvarchar(40), 
   Y1997Q1 money, Y1997Q2 money, Y1997Q3 
   money, Y1997Q4 money, Y1997Totals money)
GO

INSERT dbo.OrdersByProduct1997Pivot(Category, 
   Product, Y1997Q1, Y1997Q2, Y1997Q3, Y1997Q4) 
   SELECT CategoryName AS Category, 
      ProductName AS Product, [1] AS Y1997Q1, 
      [2] AS Y1997Q2, [3] AS Y1997Q3, [4] AS Y1997Q4
   FROM dbo.OrdersByProduct1997
   PIVOT (SUM(ProductOrders) FOR 
      Quarter IN([1], [2], [3], [4])) AS QuarterlyOrders 
   ORDER BY CategoryName, ProductName
GO

UPDATE dbo.OrdersByProduct1997Pivot 
SET Y1997Totals = ISNULL(Y1997Q1, 0) + 
   ISNULL(Y1997Q2, 0) + ISNULL(Y1997Q3, 0) + 
   ISNULL(Y1997Q4, 0)
GO
SELECT * FROM dbo.OrdersByProduct1997Pivot

This PIVOT expression (in bold) creates and inserts rows in an OrdersByProduct1997Pivot table. The UPDATE statement computes row totals by substituting 0 for NULL ProductOrders values. Updating all NULL values to 0 lets you cross-foot the resultset by inserting a row with the SUMs of the five numeric columns.

The persistent table lets you test UNPIVOT operator syntax (OrdersByProduct1997Unpivot.sql) to return a rowset that's identical to the OrdersByProduct1997 source table:

SELECT Product AS ProductName, Category 
   AS CategoryName, Quarter, ProductOrders 
FROM (SELECT Category, Product, Y1997Q1 AS [1], 
   Y1997Q2 AS [2],   Y1997Q3 AS [3], Y1997Q4 AS [4] 
   FROM dbo.OrdersByProduct1997Pivot) AS P1
   UNPIVOT (ProductOrders 
      FOR Quarter IN([1], [2], [3], [4])) 
      AS QuarterlyOrders 
GO
ADVERTISEMENT

Note that the UNPIVOT query's sub-SELECT statement that forms the first FROM clause is the PIVOT query's SELECT clause with the crosstab column names and aliases interchanged. The UNPIVOT clause is the PIVOT clause with the SUM aggregate function removed.

Use Ranking Functions and Windowing Clauses
The T-SQL TOP (n) [PERCENT] operator introduced DBAs and developers to rowsets based on the ranking of the rows that's determined by the sort order that you specify with an ORDER BY clause. SQL Server required n to be a literal integer or—with the PERCENT modifier—a float value. SQL Server 2005 expands on this by letting you substitute a variable of the bigint or float data type for the literal numerical value:

DECLARE @numRows AS bigint;
SET @numRows = 10;
SELECT TOP (@numRows) * FROM Products
   ORDER BY UnitPrice DESC
GO
DECLARE @pctRows AS float;
SET @pctRows = 12.5;
SELECT TOP (@pctRows) PERCENT * FROM Products
   ORDER BY UnitPrice DESC
GO
Back to top














Java Pro | Visual Studio Magazine | Windows Server System Magazine
.NET Magazine | Enterprise Architect | XML & Web Services Magazine
VSLive! | Thunder Lizard Events | Discussions | Newsletters | FTP Home