Reputation: 41
I've the following source table:
---------------------------------------------------------------
| Id | GroupName | RuleName | RuleText | RuleValue |
+-------------------------------------------------------------+
| 1 | Group1 | Exclude1 | Excluded (Reason1) | 1 |
+-------------------------------------------------------------+
| 1 | Group1 | Exclude2 | Excluded (Reason2) | 1 |
+-------------------------------------------------------------+
| 1 | Group1 | Exclude3 | Excluded (Reason3) | 1 |
+-------------------------------------------------------------+
| 1 | Group1 | Include1 | Included (Reason1) | 1 |
+-------------------------------------------------------------+
| 1 | Group1 | Include2 | Included (Reason2) | 1 |
+-------------------------------------------------------------+
| 2 | Group1 | Include1 | Included (Reason1) | 1 |
+-------------------------------------------------------------+
| 2 | Group1 | Exclude4 | Excluded (Reason4) | 1 |
---------------------------------------------------------------
I need to unpivot/pivot the tale to:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | GroupName | Exclude1 | Exclude2 | Exclude3 | Exclude4 | Include1 | Include2 | Exclude1RuleText | Exclude2RuleText | Exclude3RuleText | Exclude4RuleText | Include1RuleText | Include2RuleText |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 | Group1 | 1 | 1 | 1 | NULL | 1 | 1 | Excluded (Reason1) | Excluded (Reason2) | Excluded (Reason3) | NULL | Included (Reason1) | Included (Reason2) |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 2 | Group1 | NULL | NULL | NULL | 1 | 1 | NULL | NULL | NULL | NULL | Excluded (Reason4) | Included (Reason1) | NULL |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I can't quite figure out how to rename the columns.
Upvotes: 2
Views: 72
Reputation: 43636
You can use dynamic T-SQL in order to make a pivot for various columns. Here is full working example:
DROP TABLE IF EXISTS #DataSource;
CREATE TABLE #DataSource
(
[ID] INT
,[GroupName] VARCHAR(12)
,[RuleName] VARCHAR(12)
,[RuleText] VARCHAR(32)
,[RuleValue] BIT
);
INSERT INTO #DataSource ([ID], [GroupName], [RuleName], [RuleText], [RuleValue])
VALUES (1, 'Group1', 'Exclude1', 'Excluded (Reason1)', 1)
,(1, 'Group1', 'Exclude2', 'Excluded (Reason2)', 1)
,(1, 'Group1', 'Exclude3', 'Excluded (Reason3)', 1)
,(1, 'Group1', 'Include1', 'Included (Reason1)', 1)
,(1, 'Group1', 'Include2', 'Included (Reason2)', 1)
,(2, 'Group1', 'Include1', 'Included (Reason1)', 1)
,(2, 'Group1', 'Exclude4', 'Excluded (Reason4)', 1);
DECLARE @DynamicTSQLStatement NVARCHAR(MAX);
DECLARE @DynamicSelectColumns NVARCHAR(MAX);
WITH DataSource ([RowID], [RowValue]) AS
(
SELECT DISTINCT 0, [RuleName]
FROM #DataSource
UNION ALL
SELECT DISTINCT 1, [RuleName] + 'Text'
FROM #DataSource
)
SELECT @DynamicSelectColumns = STUFF
(
(
SELECT ',' + QUOTENAME([RowValue])
FROM DataSource
ORDER BY [RowID], [RowValue]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
);
SET @DynamicTSQLStatement = N'
SELECT *
FROM
(
SELECT [ID]
,[GroupName]
,[RuleName]
,CAST([RuleValue] AS VARCHAR(32))
FROM #DataSource
UNION ALL
SELECT [ID]
,[GroupName]
,[RuleName] + ''Text''
,[RuleText]
FROM #DataSource
) DS ([ID], [GroupName], [column], [value])
PIVOT
(
MAX([value]) FOR [column] IN (' + @DynamicSelectColumns + ')
) PVT
';
EXECUTE sp_executesql @DynamicTSQLStatement;
Upvotes: 1
Reputation: 39
Alternatively, you can use a Group By clause to pivot.
You'll need to adjust your functions as necessary, I'm using MAX right now since the only data you gave was 1's and possible text, assuming a 1-1 ratio. But you can use an aggregate function as well to string stuff together if there's more than one entry per column per group/id.
select
id
,GroupName
,max(
CASE
WHEN RuleName like 'Exclude1' THEN 1
ELSE NULL
END) as 'Exclude2'
,max(
CASE
WHEN RuleName like 'Exclude2' THEN 1
ELSE NULL
END) as 'Exclude2'
,max(
CASE
WHEN RuleName like 'Exclude3' THEN 1
ELSE NULL
END) as 'Exclude3'
,max(
CASE
WHEN RuleName like 'Exclude4' THEN 1
ELSE NULL
END) as 'Exclude4'
,max(
CASE
WHEN RuleName like 'Include1' THEN 1
ELSE NULL
END) as 'Include1'
,max(
CASE
WHEN RuleName like 'Include2' THEN 1
ELSE NULL
END) as 'Include2'
,max(
CASE
WHEN RuleName like 'Exclude1RuleText' THEN RuleName
ELSE NULL
END) as 'Exclude1RuleText'
,max(
CASE
WHEN RuleName like 'Exclude2RuleText' THEN RuleName
ELSE NULL
END) as 'Exclude2RuleText'
,max(
CASE
WHEN RuleName like 'Exclude3RuleText' THEN RuleName
ELSE NULL
END) as 'Exclude3RuleText'
,max(
CASE
WHEN RuleName like 'Exclude4RuleText' THEN RuleName
ELSE NULL
END) as 'Exclude4RuleText'
,max(
CASE
WHEN RuleName like 'Include1RuleText' THEN RuleName
ELSE NULL
END) as 'Include1RuleText'
,max(
CASE
WHEN RuleName like 'Include2RuleText' THEN RuleName
ELSE NULL
END) as 'Include2RuleText'
from tablename
group by
id
,GroupName
Upvotes: 0
Reputation: 29647
A pivot on a union can generate such duo pivoting.
select *
from
(
select Id, GroupName
, RuleName + 'RuleText' as Col
, RuleText as Value
from YourSourceTable
union all
select Id, GroupName
, RuleName
, format(RuleValue, 'd')
from YourSourceTable
) Src
pivot
(
max(Value)
for Col in (
[Exclude1], [Exclude2], [Exclude3], [Exclude4],
[Include1], [Include2],
[Exclude1RuleText], [Exclude2RuleText],
[Exclude3RuleText], [Exclude4RuleText],
[Include1RuleText], [Include2RuleText]
)
) Pvt
order by Id, GroupName
Upvotes: 0