Pivot is a useful function in 2005, but it still has its limits. When I first attempted to use this new feature, I was a bit disappointed. I have to admit, I usually try something before I read the details on how it works – mostly to see if something works the way I would picture it to work. As you can imagine, pivot is a nice function to use for prepping data for display, ad-hoc reporting, etc. I'll go over a trick here to make it dynamic the way I expected the pivot operator to be.
I first tried something like this:
select territoryid, OrderDate
from Sales.SalesOrderHeader h
pivot
( count(orderdate) for
OrderDate in (select OrderDate from Sales.SalesOrderHeader where OrderDate < '2001-07-10')
) p
Quite often, date is the dimension on which you would like to pivot data on – and you do not always know what range you would like. Additionally, if you would like to make this retrieval operation into a stored procedure that accepts a date range as parameters, you would now have a problem in generating a cross-tab data set using the pivot operator. How does a working query look? Here is one:
select * from
(select territoryid, OrderDate
from Sales.SalesOrderHeader) h
pivot
( count(orderdate) for
OrderDate in ([2001-07-01], [2001-07-02], [2001-07-03], [2001-07-04], [2001-07-05], [2001-07-06], [2001-07-07], [2001-07-08], [2001-07-09])
) p
The first thing to note is that pivot relies directly on table aliases; in the query above I have built a nested select that gives us the first alias table in order to build our data to pivot on. This is the basic format a query will need to be in order to use the pivot function, though you can also make use of CTE to help keep your code neat. The second thing to note is that your pivot columns must be enclosed in the [] brackets for the operation to work.
So how can we make the pivot columns dynamic? The first step is to build a delimited list of the values you wish to pivot on. For this example, we are using the AdventureWorks database (not the dimensional database, the OLTP example). We'll use a trick that worked in SQL 2000 as well to build a result set into a single delimited string using coalesce. Here is how it looks:
select @StrSql = coalesce(@StrSql + ', ', '')+ '['+convert(nvarchar(10),OrderDate,20)+']'
from Sales.SalesOrderHeader
where OrderDate < '2001-07-10'
group by OrderDate
order by OrderDate
The output of this looks like:
[2001-07-01], [2001-07-02], [2001-07-03], [2001-07-04], [2001-07-05], [2001-07-06], [2001-07-07], [2001-07-08], [2001-07-09]
Now that we have a way to build our pivot columns string, then is a simple matter of building a dynamic statement to execute:
set @StrSql =
'
select * from
(select territoryid, OrderDate
from Sales.SalesOrderHeader) h
pivot
( count(orderdate) for
OrderDate in (' + @StrSqlP +')
) p
'
exec sp_executesql @StrSql
And there you go – a better way to use the pivot function in SQL 2005. As you can image, you can add a lot of different variables to this in order to get a more dynamic result set from your query – the biggest trick is getting your delimted list of pivot columns.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5