|
Variable PIVOTING with Self-Terminating WHILE – UPDATE
By Kalman Toth, M.Phil., M.Phil.,
MCDBA, MCITP
SQL Server 2005 has introduced the PIVOT function which can be used to flip rows into columns in a fixed layout format.
What on the other hand if the number of members across columns is a variable? Well actually there is an extremely neat WHILE-UPDATE solution which even works in SQL Server 2000. It is very fast.
Assume we want to list all the EmployeeID-s for employees living in a certain city for AdventureWorks mountain mike manufacturer.
First we create a typical long SQL vertical listing where employees live.
select City=City+', '+StateProvinceCode, e.EmployeeID
into #Location
from HumanResources.Employee e
join HumanResources.EmployeeAddress a
on e.EmployeeID=a.EmployeeID
join Person.Address ad
on a.AddressID = ad.AddressID
join Person.StateProvince sp
on sp.StateProvinceID=ad.StateProvinceID
order by City, EmployeeID
Second step, we select distinct cities and prepare a string to hold the employee list for each city. Naturally, the string is finite. Usually, we don’t deal with thousands of list members in this kind of PIVOTING.
select distinct City, Employees=convert(varchar(2000), '|')
into #City
from #Location
Finally, we are ready for the dazzling WHILE-UPDATE PIVOTING. This construct is much-much faster than using a function:
while @@rowcount > 0
update c set c.Employees = c.Employees + convert(varchar(3),l.EmployeeID)+'|'
from #City c
join #Location l
on c.City=l.City
and charindex('|'+convert(varchar(3),l.EmployeeID)+'|', c.Employees, 1) = 0
To check out what happened we run a SELECT:
select * from #City
The returned results:
| City |
Employees |
| Bellevue, WA |
|9|21|22|23|27|30|68|69|74|80|95|96|110|114|115|128|142|..... |
| Berlin, HH |
|289| |
| Bordeaux, 33 |
|286| |
| Bothell, WA |
|5|35|41|67|72|164|167|179|181|222|224|248|288| |
| Calgary, AB |
|278| |
| Cambridge, ENG |
|285| |
| Cambridge, MA |
|287| |
| Carnation, WA |
|38|62|75|169|235| |
| Detroit, MI |
|275| |
| Duluth, MN |
|277| |
| Duvall, WA |
|16|37|88|156|160|163|165|199|240|256| |
| Edmonds, WA |
|13|14|58|60|61|63|65|81|89|91|99|104|107|108|120|137|141|194|196|215|229|243|250|254|255| |
| Everett, WA |
|2|8|20|40|46|47|59|79|106|119|123|136|185|190|204|206|209|262| |
| Gold Bar, WA |
|49|139|166|191|242| |
| Index, WA |
|94|161|216|251|260| |
| Issaquah, WA |
|28|54|66|90|102|111|117|127|149|150|154|176|188|212|273| |
| Kenmore, WA |
|17|24|87|118|135|153|158|170|200|252|253|263| |
| Kent, WA |
|202| |
| Melbourne, VIC |
|290| |
| Memphis, TN |
|279| |
| Minneapolis, MN |
|4| |
| Monroe, WA |
|1|15|26|33|39|76|112|122|148|168|171|184|208|214| |
| Nevada, UT |
|276| |
| Newport Hills, WA |
|44|70|82|103|109|130|155| |
| Ottawa, ON |
|282| |
| Portland, OR |
|280| |
| Redmond, WA |
|3|6|19|42|48|55|129|131|132|146|157|189|192|197|213|237|261|264|265|268|271| |
| Renton, WA |
|11|12|34|77|121|140|145|195|198|218|225|238|241|259|267|270|284| |
| Sammamish, WA |
|50|71|78|84|93|113|124|125|133|201|211|219|220|232|236|269|274| |
| San Francisco, CA |
|217|281| |
| Seattle, WA |
|7|18|25|29|31|43|51|52|53|56|57|64|73|83|85|86|97|98|......| |
| Snohomish, WA |
|10|32|36|45|92|134|138|187|230|246| |
|
| The Best SQL Server
2005 Training in the World |
 |
|