SQL Clone
SQLServerCentral is supported by Redgate
 
Log in  ::  Register  ::  Not logged in
 
 
 


Pivot table for Microsoft SQL Server


Pivot table for Microsoft SQL Server

Author
Message
SwePeso
SwePeso
SSC-Insane
SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)

Group: General Forum Members
Points: 20161 Visits: 3433

Comments posted to this topic are about the content posted at http://www.sqlservercentral.com/columnists/plarsson/pivottableformicrosoftsqlserver.asp




N 56°04'39.16"
E 12°55'05.25"
David Coster
David Coster
Valued Member
Valued Member (62 reputation)Valued Member (62 reputation)Valued Member (62 reputation)Valued Member (62 reputation)Valued Member (62 reputation)Valued Member (62 reputation)Valued Member (62 reputation)Valued Member (62 reputation)

Group: General Forum Members
Points: 62 Visits: 148
Very nice! I will probably use this at some time. Thanks heaps!
Mike Dougherty
Mike Dougherty
Mr or Mrs. 500
Mr or Mrs. 500 (580 reputation)Mr or Mrs. 500 (580 reputation)Mr or Mrs. 500 (580 reputation)Mr or Mrs. 500 (580 reputation)Mr or Mrs. 500 (580 reputation)Mr or Mrs. 500 (580 reputation)Mr or Mrs. 500 (580 reputation)Mr or Mrs. 500 (580 reputation)

Group: General Forum Members
Points: 580 Visits: 952
Have you considered building the update string inside the loop, but executing it after you have iterated all the columns? O(1) < O(n)

Also, do you have any comments/caveats on the security implication of dynamic SQL used in this process?
RyanRandall
RyanRandall
SSCertifiable
SSCertifiable (7.7K reputation)SSCertifiable (7.7K reputation)SSCertifiable (7.7K reputation)SSCertifiable (7.7K reputation)SSCertifiable (7.7K reputation)SSCertifiable (7.7K reputation)SSCertifiable (7.7K reputation)SSCertifiable (7.7K reputation)

Group: General Forum Members
Points: 7713 Visits: 4652

Thanks Peter - nice looking article.

I've not read the whole article yet (that's for when I have more time), but I wonder how your approach compares with the 'classic' crosstab/pivot table approaches...

http://www.sqlteam.com/item.asp?ItemID=2955
http://weblogs.sqlteam.com/jeffs/archive/2005/05/02/4842.aspx

If anyone has time to evaluate this, I'd be very grateful!



Ryan Randall

Solutions are easy. Understanding the problem, now, that's the hard part.
SwePeso
SwePeso
SSC-Insane
SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)

Group: General Forum Members
Points: 20161 Visits: 3433

Yes, in my very first early version. Then I realized that I could potentially come across the 8000 character limit for varchars.




N 56°04'39.16"
E 12°55'05.25"
SwePeso
SwePeso
SSC-Insane
SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)

Group: General Forum Members
Points: 20161 Visits: 3433

Thanks Ryan.

I have tried to keep the dynamic SQL executions to a minimum for obvious speed reasons. What I think I have provided is a base for creating crosstabs/pivots for users to learn from and hopefully, evolve with.

There are some things to do with the code to make it "universal". But I thought it would be best to show how to start from the beginning.

To make the code "universal" you first have to build a dynamic query for preaggregating the data in #Aggregates. That is not very hard to to! Also, you must change the parameters to the future stored procedure to allow two fully qualified names such as RemoteServer1.OwnerLocal.ThatTable.ThisField for the rows and columns. Even the CellData field in #Aggregates could be taken from a parameter this way and called with 'SUM(x)' or 'COUNT(y)'. You catch my drift.

An example could be

EXEC dbo.CrossTabPivot 'Table1.OfficeName', 'Table2.Category', 'COUNT(t)', ...




N 56°04'39.16"
E 12°55'05.25"
SwePeso
SwePeso
SSC-Insane
SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)

Group: General Forum Members
Points: 20161 Visits: 3433

Yes, SQL injection could possible be an issue here, if the data in ColumnText is written such way.

But since the beginning of the UPDATE-statement is hardwired with "UPDATE", I right now can't see a way to manipulate the statement to run SQL injection code.




N 56°04'39.16"
E 12°55'05.25"
teleMarinaV
teleMarinaV
SSC Veteran
SSC Veteran (224 reputation)SSC Veteran (224 reputation)SSC Veteran (224 reputation)SSC Veteran (224 reputation)SSC Veteran (224 reputation)SSC Veteran (224 reputation)SSC Veteran (224 reputation)SSC Veteran (224 reputation)

Group: General Forum Members
Points: 224 Visits: 4

I think it is worth mentioning the restrictions of that method such as:

- MAX number of columns (?),

- MAX total row length (8K).

I've used similar method using cursor instead of column table.





John Rempel
John Rempel
Ten Centuries
Ten Centuries (1.4K reputation)Ten Centuries (1.4K reputation)Ten Centuries (1.4K reputation)Ten Centuries (1.4K reputation)Ten Centuries (1.4K reputation)Ten Centuries (1.4K reputation)Ten Centuries (1.4K reputation)Ten Centuries (1.4K reputation)

Group: General Forum Members
Points: 1407 Visits: 292
Perfect timing! I was able to use this logic for a report today. It made short work out of an otherwise arduous task.

Thanks.
SwePeso
SwePeso
SSC-Insane
SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)SSC-Insane (20K reputation)

Group: General Forum Members
Points: 20161 Visits: 3433
Max number of columns are restricted to what datatype you use for #Aggregate column. The total size for a row is 8,060 bytes. Using 60 bytes for RowText leaves us 8,000 bytes for the rest of the columns and since INT is 4 bytes, we can potentially have 2,000 columns. If you prefer SMALLINT (2 bytes) as #Aggregate column, you could theoretically have 4,000 columns.


N 56°04'39.16"
E 12°55'05.25"
Go


Permissions

You can't post new topics.
You can't post topic replies.
You can't post new polls.
You can't post replies to polls.
You can't edit your own topics.
You can't delete your own topics.
You can't edit other topics.
You can't delete other topics.
You can't edit your own posts.
You can't edit other posts.
You can't delete your own posts.
You can't delete other posts.
You can't post events.
You can't edit your own events.
You can't edit other events.
You can't delete your own events.
You can't delete other events.
You can't send private messages.
You can't send emails.
You can read topics.
You can't vote in polls.
You can't upload attachments.
You can download attachments.
You can't post HTML code.
You can't edit HTML code.
You can't post IFCode.
You can't post JavaScript.
You can post emoticons.
You can't post or upload images.

Select a forum







































































































































































SQLServerCentral


Search