What's the best way to get a key-value pair result set that represents column-value in a row?
Given the following table A with only 1 row
Column1 Column2 Column3 ...
Value1 Value2 Value3
I want to query it and insert into another table B:
Key Value
Column1 Value1
Column2 Value2
Column3 Value3
A set of columns in table A is not known in advance.
NOTE: I was looking at FOR XML and PIVOT features as well as dynamic SQL to do something like this:
DECLARE @sql nvarchar(max)
SET @sql = (SELECT STUFF((SELECT ',' + column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name='TableA'
ORDER BY column_name FOR XML PATH('')), 1, 1, ''))
SET @sql = 'SELECT ' + @sql + ' FROM TableA'
EXEC(@sql)
I think you're halfway there. Just use
UNPIVOT
anddynamic SQL
as Martin recommended:Results:
There is a caveat, of course. All your columns will need to be the same data type for the above code to work. If they are not, you will get this error:
In order to get around this, you'll need to create two column string statements. One to get the columns and one to cast them all as the data type for your Val column.
For multiple column types:
A version where there is no dynamic involved. If you have column names that is invalid to use as element names in XML this will fail.
A working sample:
Result:
Update
For a query with more than one table you could use
for xml auto
to get the table names in the XML. Note, if you use alias for table names in the query you will get the alias instead.SQL Fiddle
Perhaps you're making this more complicated than it needs to be. Partly because I couldn't wrap my little brain around the number of
PIVOT
/UNPIVOT
/whatever combinations and a dynamic SQL "sea of red" would be necessary to pull this off. Since you know the table has exactly one row, pulling the value for each column can just be a subquery as part of a set ofUNION
ed queries.Result (I only created 4 columns, but this would work for any number):
The most efficient thing in the world? Likely not. But again, for a one-row table, and hopefully a one-off task, I think it will work just fine. Just watch out for column names that contain apostrophes, if you allow those things in your shop...
EDIT sorry, couldn't leave it that way. Now it will handle apostrophes in column names and other sub-optimal naming choices.