I have a SQL Server table that looks like this:
RESOURCE | DESCRIPTION | VALUE
Test A Name | Resource A-xyz
Test A | Height | 20
Test A | Unit | ft
Test A | Location | Site 1
Test B | Volume | 30
Test C | Width | 10
Test C | Unit | in
I would like to get it into this format:
RESOURCE | Name | Height | Unit | Location | Volume | Width
Test A | Resource A-xyz | 20 | ft | Site 1 | |
Test B | | | | | 30 |
Test C | | | in | | | 10
One of the issues that I have is that there is no set pattern for description; for example, resource "Test B" might have all of the same descriptions as "Test A", while "Test C", might be missing some, and "Test D" might have a totally different set.
So far Google is suggesting that I want to use a pivot table, but I am still not sure how to do that with the above data.
The resulting column list is based on the ordering you provide within the PIVOT
:
SELECT *
FROM Table1
PIVOT(MAX(VALUE) FOR DESCRIPTION IN (Name,Height,Unit,Location,Volume,Width))p
Demo: SQL Fiddle
If you have changing values for DESCRIPTION
it's worthwhile to build this query dynamically, there are plenty of good examples for 'dynamic pivot' to be found.
try this code:
SELECT resource,Name,Height,Unit,Location,Volume,Width
FROM
#T1 AS SourceTable
PIVOT
(
max(value)
FOR description IN ([Name],[Height],[Unit],[Location],[Volume],[Width])
) AS PivotTable
ORDER BY 1
If you don't want to hardcode the columns and want to generate same view on the fly, you can use this. This will generate dynamic pivot
CREATE TABLE demo
(
RESOURCE VARCHAR(100),
DESCRIPTION VARCHAR(100), VALUE VARCHAR(100)
)
INSERT INTO demo VALUES
('Test A' , 'Name' , 'Resource A-xyz')
,('Test A' , 'Height' , '20')
,('Test A' , 'Unit' , 'ft')
,('Test A' , 'Location' , 'Site 1')
,('Test B' , 'Volume' , '30')
,('Test C' , 'Width' , '10')
,('Test C' , 'Unit' , 'in')
SELECT DISTINCT DESCRIPTION INTO #tbl FROM demo
//Get list of values to be pivoted
DECLARE @var NVARCHAR(1000)=''
SELECT @var = @var +', ' + DESCRIPTION FROM #tbl
SELECT @var = SUBSTRING(@var, 2, LEN(@var))
SELECT @var
DECLARE @query NVARCHAR(2000) = 'SELECT * FROM demo PIVOT(MAX(VALUE) FOR DESCRIPTION IN ('+ @var + '))p'
EXEC sp_executesql @query
In the end, I did the following:
- Selected all distinct descriptions (more than 70!).
- Created a table that had resource and every single distinct description as fields
- Populated resource column distinct resource names
- Ran a series of
updates to populate remaining columns for each distinct resource
name.
For example
CREATE TABLE #tb1
(
[RESOURCE] varchar(100),
[FIELD1] varchar(100),
[FIELD2] varchar(50),
.
.
.
[LAST FIELD] varchar(50),
)
INSERT INTO #tb1 (RESOURCE)
SELECT DISTINCT RESOURCE FROM tb2
ORDER BY Resource ASC
UPDATE #tb1 SET [FIELD1] = (SELECT VALUE FROM tb2 WHERE Resource = #tb1.Resource and Property = [FIELD1])
.
.
.
UPDATE #tb1 SET [LAST FIELD] = (SELECT VALUE FROM tb2 WHERE Resource = #tb1.Resource and Property = [LAST FIELD])