|
I've come across this question quite a few times.
Imagine a scenario where you have a wide table that you'd like to normalize, at least in view or faรงade (or perhaps in a data transformation layer) - You'd like to un-pivot it, rotating columns into rows. For a sample, I'll use the questioner's scenario of a Person table with a variety of attributes. Don't get hung-up on the table or whether it's already normalized (the sample came directly from a user who had a rather unique need), the point is simply rotating columns into rows. Table: Person
You'd like to return a set like the following:
(rows truncated for some brevity) SQL Server 2005 offers the UNPIVOT operator of the FROM clause, which can made quick (albeit unintuitively and inflexibly) work of this specific need. SELECT The use of the derived table in the FROM clause is
purely to cast the columns to a common data type, as this is a
requirement of the UNPIVOT operator. Otherwise all of the source
columns would need to have the same type (precisely the same
type). With SQL Server 2000 you can do this via simple unions or temporary tables SELECT In this case we've made the common type sql_variant, though obviously you should alter according to your data. We've also decided to eliminate null values (so there aren't null property rows), though that depends upon the need. Another option is to make a programmatically flexible
alternative that automatically adapts to the schema of the table
(within constraints). For instance consider the following
script. SET NOCOUNT ON DECLARE @table sysname DECLARE @id_field sysname DECLARE @sql varchar(8000) -- create the schema of the resulting table SELECT @sql = @sql + 'UNION ALL SELECT '+@id_field+', N''' IF (LEN(@sql) >0) In this case it uses the object schema, though you could alter it to go against a property table or the like. Standard disclaimers about injection attacks and all of that apply (presumably you won't be calling this with untrusted input), and of course it won't work if you have composite keys, or if you have so many columns that the resulting SQL exceeds 8000 characters. Adapt accordingly. It also does no sorting, so add as you need it. |
(C) Dennis Forbes 2007