Pivot Header Data in row using sql server - sql

Is there any way to make table pivot in sql server like such a way.
I have data like
| OldItem | NewItem |
---------------------
| HD1 | 365 |
I need output like below.
| Name | Value1 |
---------------------
| OldItem | HD1 |
| NewItem | 365 |
Thanks in advance.

Please try using UNPIVOT. Sample given is for static two rows.
SELECT Name, Value1
FROM
(SELECT *
FROM tbl) p
UNPIVOT
(Value1 FOR Name IN
(OldItem, NewItem)
)AS unpvt;

The following works for me:
Create Table #Values (OldItem char(3),NewItem int);
INSERT INTO #Values (OldItem, NewItem)
VALUES ('HD1',365)
,('HD2',300)
,('HD3',200);
With Values_Ordered AS
(
SELECT OldItem, NewItem, row_number() OVER (ORDER BY OldItem) AS Sequence
FROM #Values
)
SELECT 'OldItem' AS Name,
min(CASE WHEN Sequence = 1 THEN OldItem ELSE NULL END) AS Value1,
min(CASE WHEN Sequence = 2 THEN OldItem ELSE NULL END) AS Value2,
min(CASE WHEN Sequence = 3 THEN OldItem ELSE NULL END) AS Value3
FROM Values_Ordered
UNION ALL
SELECT 'NewItem' AS Name,
min(CASE WHEN Sequence = 1 THEN CAST(NewItem AS CHAR(3)) ELSE NULL END) AS Value1,
min(CASE WHEN Sequence = 2 THEN CAST(NewItem AS CHAR(3)) ELSE NULL END) AS Value2,
min(CASE WHEN Sequence = 3 THEN CAST(NewItem AS CHAR(3)) ELSE NULL END) AS Value3
FROM Values_Ordered

And here is my little code :D
DECLARE #dataTable TABLE (OldItem VARCHAR(10), NewItem INT)
INSERT INTO #dataTable SELECT 'HD1', 365
INSERT INTO #dataTable SELECT 'HD2', 300
INSERT INTO #dataTable SELECT 'HD3', 200
INSERT INTO #dataTable SELECT 'HD4', 200
--first select data what you need and add upcoming new column name
SELECT 'Value' + CAST(ROW_NUMBER() OVER (ORDER BY OldITem) AS VARCHAR) AS NewColumn, 'OldItem' as RowName, OldItem AS Item
INTO #SelectedData
FROM #dataTable
WHERE OldItem IN ('HD1', 'HD2', 'HD3')
UNION ALL
SELECT 'Value' + CAST(ROW_NUMBER() OVER (ORDER BY OldITem) AS VARCHAR) AS NewColumn, 'NewItem' as RowName, CAST(NewItem AS VARCHAR) AS Item
FROM #dataTable
WHERE OldItem IN ('HD1', 'HD2', 'HD3')
--Collect what column names will be
DECLARE #columns NVARCHAR(MAX) = (
SELECT STUFF(
(SELECT DISTINCT ', [' + NewColumn + ']'
FROM #SelectedData
FOR XML PATH ('')),
1, 2, '' )
)
-- create dynamic code for pivot
DECLARE #dynamicSQL AS NVARCHAR(MAX);
SET #dynamicSQL = N'
SELECT RowName, ' + #columns + '
FROM #SelectedData
PIVOT (MIN(Item) FOR NewColumn IN (' + #columns + ')) AS T
';
EXEC sp_executesql #dynamicSQL

Related

How to pivot data in SQL with multiple conditions

I am working on a data where it looks like this
I want to pivot it in this way :
I have written in this way :
select *
from (select * FROM records) as test
PIVOT (
max(value) for
[Question_ID] in ((SELECT distinct [Question_ID] from records order by 1))) AS PivotTable
Can you please help me?
If you know the number of columns in PIVOT, you can directly hardcode like below.
SELECT * FROM
(
SELECT * FROM test
) t
PIVOT (
MAX(value) for
[Question_ID] in ([120],[122],[149],[150],[151],[189],[253],[554],[774] )) AS Pivot_Table
If not,you have to use Dynamic Pivot table for unknown number of column values.
DECLARE
#columns NVARCHAR(MAX) = '',
#sql NVARCHAR(MAX) = '';
-- select the QuestionIDs
SELECT
#columns+=QUOTENAME(Question_ID) + ','
FROM
test
GROUP BY Question_ID
ORDER BY Question_ID;
-- remove the last comma
SET #columns = LEFT(#columns, LEN(#columns) - 1);
-- construct dynamic SQL
SET #sql ='
SELECT * FROM
(
SELECT * FROM TEST
) t
PIVOT(
MAX(value) for
[Question_ID] IN ('+ #columns +')
) AS pivot_table;';
-- execute the dynamic SQL
EXECUTE sp_executesql #sql;
CHECK DEMO HERE
you got your wish result
select *
from (select * FROM #temp) as test--your table name replace with #temp
PIVOT (
max(value) for
[Question_ID] in ([120],[122],[149],[150],[151],[189],[253],[554],[774] )) AS PivotTable
or if you want to dynamic your query
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(Question_ID)
FROM #temp c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
--print #cols
set #query = 'SELECT ID, ' + #cols + ' from
(
select ID
, Question_ID
, [Value]
from #temp
) x
pivot
(
max([Value])
for [Question_ID] in (' + #cols + ')
) p '
execute(#query)
drop table #temp
----------
If you are sure that the number of columns will not change, then you can use case statement
CREATE TABLE #TBL (ID INT, Question_ID INT, [Value] VARCHAR(20))
INSERT INTO #TBL VALUES
(1,149,'abc'),(1,150,'def'),(1,151,'aff'),(1,122,'www'),
(2,120,'add'),(2,150,'sub'),(2,189,'asf'),(3,253,'asd'),
(3,150,'gfre'),(3,554,'cvew'),(3,744,'qwert')
-- aNSWER
SELECT
ID,
MAX(CASE WHEN Question_ID = 149 THEN [Value] END) AS '149',
MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
MAX(CASE WHEN Question_ID = 151 THEN [Value] END) AS '151',
MAX(CASE WHEN Question_ID = 122 THEN [Value] END) AS '122',
MAX(CASE WHEN Question_ID = 120 THEN [Value] END) AS '120',
MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
MAX(CASE WHEN Question_ID = 189 THEN [Value] END) AS '189',
MAX(CASE WHEN Question_ID = 253 THEN [Value] END) AS '253',
MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
MAX(CASE WHEN Question_ID = 554 THEN [Value] END) AS '554',
MAX(CASE WHEN Question_ID = 744 THEN [Value] END) AS '744'
FROM #TBL
GROUP BY ID
DROP TABLE #TBL
Output
ID 149 150 151 122 120 150 189 253 150 554 744
1 abc def aff www NULL def NULL NULL def NULL NULL
2 NULL sub NULL NULL add sub asf NULL sub NULL NULL
3 NULL gfre NULL NULL NULL gfre NULL asd gfre cvew qwert

Multiple Rows into One Row multiple columns

We need to list all numbers as a flat data set, how can we do that?
Table Name: Telephone
ID TYPE NUMBER
==================================
123 MN 042153939
123 HN 2242116
123 MN 1234567890
123 HN 12345678
Create Table Telephone
(
ID Integer,
Type char(3),
Number Varchar(20)
);
insert into Telephone values
(123, 'MN', '042153939'),
(123, 'HN', '2242116'),
(123, 'MN', '1234567890'),
(123, 'HN', '12345678');
I want SQL to return data in this format
ID MN#1 Mn#2 HN#1 HN#2
================================================
123 042153939 1234567890 2242116 12345678
Dynamic approach
Init
DROP TABLE IF EXISTS #Telephone;
CREATE TABLE #Telephone(ID INT,Type CHAR(3),Number VARCHAR(20));
INSERT INTO #Telephone (ID,Type,Number) VALUES
(123, 'MN', '042153939'),
(123, 'HN', '2242116'),
(123, 'MN', '1234567890'),
(123, 'HN', '12345678');
The code
DECLARE #ColumnList NVARCHAR(MAX);
SELECT #ColumnList = STUFF((SELECT ',[' + RTRIM(t.[Type]) + '#'
+ CONVERT(NVARCHAR(255),ROW_NUMBER()OVER(PARTITION BY t.[Type] ORDER BY t.ID)) + ']'
FROM #Telephone t FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)'),1,1,'')
;
DECLARE #sql NVARCHAR(MAX) = '';
SET #sql = N'
SELECT ID,' + #ColumnList + N'
FROM (
SELECT t.ID,t.Number, RTRIM(t.[Type]) + ''#'' + CONVERT(NVARCHAR(255),ROW_NUMBER()OVER(PARTITION BY t.[Type] ORDER BY t.ID)) AS [Type]
FROM #Telephone t
) a
PIVOT(MAX(a.Number) FOR a.Type IN (' + #ColumnList + N')) p
'
;
--PRINT #sql
IF #sql IS NOT NULL EXEC(#sql);
try pivoting like below :
SELECT first_column AS <first_column_alias>,
[pivot_value1], [pivot_value2], ... [pivot_value_n]
FROM
(<source_table>) AS <source_table_alias>
PIVOT
(
aggregate_function(<aggregate_column>)
FOR <pivot_column> IN ([pivot_value1], [pivot_value2], ... [pivot_value_n])
) AS <pivot_table_alias>;
We can try using a pivot query with the help of ROW_NUMBER():
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY TYPE DESC, NUMBER) rn
FROM Telephone
)
SELECT
ID,
MAX(CASE WHEN rn = 1 THEN NUMBER END) AS [MN#1],
MAX(CASE WHEN rn = 2 THEN NUMBER END) AS [MN#2],
MAX(CASE WHEN rn = 3 THEN NUMBER END) AS [HN#3],
MAX(CASE WHEN rn = 4 THEN NUMBER END) AS [HN#4]
FROM cte
GROUP BY ID;
You may try this. with row_number() and pivot.
For more info about pivot you may find this link PIVOT.
; with cte as (
select row_number() over (partition by type order by id ) as Slno, * from Telephone
)
, ct as (
select id, type + '#' + cast(slno as varchar(5)) as Type, values from cte
)
select * from (
select * from ct
) as d
pivot
( max(values) for type in ( [MN#1],[Mn#2],[HN#1],[HN#2] )
) as p

Pivot SQL query output

I have a requirement where my query will return output something like this:
PermissionType IsAllowed
-------------------------
IsEdit | 1
IsDelete | 0
isRemove | 1
isPrint | 1
isReport | 0
-- | -
-- | -
-- | -
--------------------------
These rows can be dynamic depending upon the filter criteria I will pass.
So now I want to convert the above resultset to the following:
IsEdit | IsDelete | IsRemove | IsPrint | IsReport | -- | -- | --
--------------------------------------------------------------------
1 | 0 | 1 | 1 | 0 | - | - | -
I tried to use the pivot here but it asks the Column Names to be pivoted into the output and this is dynamic in my case, also it needed an aggregate function for FOR but I don't have any calculation in my case.
Anyone please help me on this.
Then try this Dynamic sql
IF OBJECT_ID('dbo.temp')IS NOT NULL
DROP TABLE temp
;WITH Cte(PermissionType, IsAllowed)
AS
(
SELECT 'IsEdit' , 1 UNION ALL
SELECT 'IsDelete' , 0 UNION ALL
SELECT 'isRemove' , 1 UNION ALL
SELECT 'isPrint' , 1 UNION ALL
SELECT 'isReport' , 0
)
SELECT *,ROW_NUMBER()OVER(ORDER BY (SELECT 1)) AS Seq INTO
temp FROM Cte
DECLARE #Sql nvarchar(max),
#Sqlcol nvarchar(max),
#ISNULLSqlcol nvarchar(max)
SELECT #Sqlcol=STUFF((SELECT ', '+QUOTENAME(PermissionType)
FROM temp ORDER BY Seq FOR XML PATH ('')),1,1,'')
SELECT #ISNULLSqlcol=STUFF((SELECT ', '+'MAX('+QUOTENAME(PermissionType) +') AS '+QUOTENAME(PermissionType)
FROM temp ORDER BY Seq FOR XML PATH ('')),1,1,'')
SET #Sql='
SELECT '+#ISNULLSqlcol+'
FROM(
SELECT * FROM temp
)AS SRC
PIVOT
(
MAX(IsAllowed) FOR PermissionType IN ('+#Sqlcol+')
) AS PVT '
PRINT #Sql
EXEC (#Sql)
IsEdit IsDelete isRemove isPrint isReport
--------------------------------------------------
1 0 1 1 0
With pivot and dynamic sql you can create a query that will include a different number of columns:
if OBJECT_ID('Test') is not null
drop table [dbo].[Test]
CREATE TABLE [dbo].[Test](PermissionType varchar(20), IsAllowed int)
insert into [dbo].[Test] values
('IsEdit' , 1)
,('IsDelete', 0)
,('isRemove', 1)
,('isPrint' , 1)
,('isReport', 0)
--this variable holds all the dates that will become column names
declare #permissionTypes nvarchar(max) = ''
--this variable contains the TSQL dinamically generated
declare #sql nvarchar(max) = ''
select #permissionTypes = #permissionTypes + ', ' + quotename(PermissionType)
from [dbo].[Test]
set #permissionTypes = RIGHT(#permissionTypes, len(#permissionTypes)-2)
set #sql = concat(
'select *
from [dbo].[Test]
pivot
(
max(isallowed)
for PermissionType in (', #permissionTypes, ')
) piv '
)
exec(#sql)
Result:
Adding a new row:
insert into [dbo].[Test] values
('IsNew' , 1)
Causes a new column to be created:

Pivoting in SQL

I would like some help pivoting. I have a dataset in SQL that looks like this
ID-----------VisitDate----------Metric------Value
1001---------2012-01-01---------Cajun-------40
1001---------2012-01-02---------Cajun-------30
1001---------2012-01-01---------Ham---------20
1003---------2012-01-02---------Ham---------10
1003---------2012-01-03---------Beef--------10
How can I pivot this dataset so that I transform it from long to wide format based on the ID and VisitDate Columns, so the dataset would look something like this:
ID-----------VisitDate----------Cajun------Ham--------Beef
1001---------2012-01-01---------40---------20---------Null
1001---------2012-01-02---------30---------Null-------Null
1003---------2012-01-02---------Null-------10---------Null
1003---------2012-01-03---------Null-------Null-------10
If you're sure that the value of Metric will only consists of Cajun, Ham and Beef, then this will do it:
SELECT
Id,
VisitDate,
Cajun = MAX(CASE WHEN Metric = 'Cajun' THEN Value END),
Ham = MAX(CASE WHEN Metric = 'Ham' THEN Value END),
Beef = MAX(CASE WHEN Metric = 'Beef' THEN Value END)
FROM YourTable
GROUP BY ID, VisitDate
ORDER BY ID, VisitDate
On the other hand, if you don't know the value of Metric, then you can use a Dynamic Cross Tab. For reference: http://www.sqlservercentral.com/articles/Crosstab/65048/
DECLARE #sql1 VARCHAR(4000) = ''
DECLARE #sql2 VARCHAR(4000) = ''
DECLARE #sql3 VARCHAR(4000) = ''
SELECT #sql1 =
'SELECT
ID
,VisitDate'
+ CHAR(10)
SELECT #sql2 = #sql2 +
' ,MAX(CASE WHEN Metric = ''' + Metric + ''' THEN Value END) AS [' + Metric + ']' + CHAR(10)
FROM(
SELECT DISTINCT Metric FROM YourTable
)t
SELECT #sql3 =
'FROM YourTable
GROUP BY ID, VisitDate
ORDER BY ID, VisitDate
'
PRINT(#sql1 + #sql2 + #sql3)
EXEC (#sql1 + #sql2 + #sql3)
RESULT
ID VisitDate Beef Cajun Ham
----------- ---------- ----------- ----------- -----------
1001 2012-01-01 NULL 40 20
1001 2012-01-02 NULL 30 NULL
1003 2012-01-02 NULL NULL 10
1003 2012-01-03 10 NULL NULL
Here's a link to sqlfiddle:
http://sqlfiddle.com/#!3/0445e/1
Here's how it looks like using PIVOT:
SELECT
ID,
VisitDate,
Cajun,
Ham,
Beef
FROM (
SELECT
ID,
VisitDate,
Metric,
Value
FROM
Bleh
) AS SourceTable PIVOT (
MAX (Value) FOR Metric IN (Cajun, Ham, Beef)
) AS PivotTable
Use PIVOT to get the result. Check the result in Fiddler
Ref. to learn SQL SERVER – PIVOT and UNPIVOT Table Examples
SELECT id,
visitdate,
SUM([Cajun]) AS [Cajun],
SUM([Ham]) AS [Ham],
SUM([beef]) AS [beef]
FROM Test AS A
PIVOT(MIN(A.value) FOR A.metric IN ([Cajun],[Ham],[beef])) AS B
GROUP BY id, visitdate

How can I query row data as columns?

I'm sure I'm missing something here.
I have a dataset like this:
FK RowNumber Value Type Status
1 1 aaaaa A New
1 2 bbbbb B Good
1 3 ccccc A Bad
1 4 ddddd C Good
1 5 eeeee B Good
2 1 fffff C Bad
2 2 ggggg A New
2 3 hhhhh C Bad
3 1 iiiii A Good
3 2 jjjjj A Good
I'd like to query the top 3 results and Pivot them as columns, so the end result set looks like this:
FK Value1 Type1 Status1 Value2 Type2 Status2 Value3 Type3 Status3
1 aaaaa A New bbbbb B Good ccccc A Bad
2 fffff C Bad ggggg A New hhhhh C Bad
3 iiiii A Good jjjjj A Good
How can I accomplish this in SQL Server 2005?
I have been attempting this using PIVOT, but I am still very unfamiliar with that keyword and cannot get it to work the way I want.
SELECT * --Id, [1], [2], [3]
FROM
(
SELECT Id, Value, Type, Status
, ROW_NUMBER() OVER (PARTITION BY Id ORDER Status, Type) as [RowNumber]
FROM MyTable
) as T
PIVOT
(
-- I know this section doesn't work. I'm still trying to figure out PIVOT
MAX(T.Value) FOR RowNumber IN ([1], [2], [3]),
MAX(T.Type) FOR RowNumber IN ([1], [2], [3]),
MAX(T.Status) FOR RowNumber IN ([1], [2], [3])
) AS PivotTable;
My actual data set is a bit more complex than this, and I need the top 10 records, not the top 3, so I don't want to simply do CASE WHEN RowNumber = X THEN... for each one.
Update
I tested all the answers below, and found most of them seem about the same with no apparent performance difference in smaller data sets (around 3k records), however there was a slight difference when running the queries against larger data sets.
Here are the results of my tests using 80,000 records and querying for 5 columns in the top 10 rows, so my end result set was 50 columns + the Id column. I'd suggest you test them on your own to decide which one works best for you and your environment.
bluefoot's answer of unpivoting and re-pivoting the data averaged the fastest at about 12 seconds. I also liked this answer because I found it easiest to read and maintain.
Aaron's answer and koderoid's answer both suggest using a MAX(CASE WHEN RowNumber = X THEN ...), and was close behind averaging at around 13 seconds.
Rodney's answer of using multiple PIVOT statements averaged around 16 seconds, although it might be faster with fewer PIVOT statements (my tests had 5).
And the first half of Aaron's answer that suggested using a CTE and OUTER APPLY was the slowest. I don't know how long it would take to run because I cancelled it after 2 minutes, and that was with around 3k records, 3 rows, and 3 columns instead of 80k records, 10 rows, and 5 columns.
You can do an UNPIVOT and then a PIVOT of the data. this can be done either statically or dynamically:
Static Version:
select *
from
(
select fk, col + cast(rownumber as varchar(1)) new_col,
val
from
(
select fk, rownumber, value, cast(type as varchar(10)) type,
status
from yourtable
) x
unpivot
(
val
for col in (value, type, status)
) u
) x1
pivot
(
max(val)
for new_col in
([value1], [type1], [status1],
[value2], [type2], [status2],
[value3], [type3])
) p
see SQL Fiddle with demo
Dynamic Version, this will get the list of columns to unpivot and then to pivot at run-time:
DECLARE #colsUnpivot AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX),
#colsPivot as NVARCHAR(MAX)
select #colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name not in ('fk', 'rownumber')
for xml path('')), 1, 1, '')
select #colsPivot = STUFF((SELECT ','
+ quotename(c.name
+ cast(t.rownumber as varchar(10)))
from yourtable t
cross apply
sys.columns as C
where C.object_id = object_id('yourtable') and
C.name not in ('fk', 'rownumber')
group by c.name, t.rownumber
order by t.rownumber
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query
= 'select *
from
(
select fk, col + cast(rownumber as varchar(10)) new_col,
val
from
(
select fk, rownumber, value, cast(type as varchar(10)) type,
status
from yourtable
) x
unpivot
(
val
for col in ('+ #colsunpivot +')
) u
) x1
pivot
(
max(val)
for new_col in
('+ #colspivot +')
) p'
exec(#query)
see SQL Fiddle with Demo
Both will generate the same results, however the dynamic is great if you do not know the number of columns ahead of time.
The Dynamic version is working under the assumption that the rownumber is already a part of the dataset.
You can try to do the pivot in three separate pivot statements. Please give this a try:
SELECT Id
,MAX(S1) [Status 1]
,MAX(T1) [Type1]
,MAX(V1) [Value1]
--, Add other columns
FROM
(
SELECT Id, Value , Type, Status
, 'S' + CAST(ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Status, Type) AS VARCHAR(10)) [Status_RowNumber]
, 'T' + CAST(ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Status, Type) AS VARCHAR(10)) [Type_RowNumber]
, 'V' + CAST(ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Status, Type) AS VARCHAR(10)) [Value_RowNumber]
FROM MyTable
) as T
PIVOT
(
MAX(Status) FOR Status_RowNumber IN ([S1], [S2], [S3],[S4],[S5],[S6],[S7],[S8],[S9],[S10])
)AS StatusPivot
PIVOT(
MAX(Type) FOR Type_RowNumber IN ([T1], [T2], [T3],[T4],[T5],[T6],[T7],[T8],[T9],[T10])
)AS Type_Pivot
PIVOT(
MAX(Value) FOR Value_RowNumber IN ([V1], [V2], [V3],[V4],[V5],[V6],[V7],[V8],[V9],[V10])
)AS Value_Pivot
GROUP BY Id
I don't know the full scope of the criteria for selecting the top ten records, but this produces and output that may get you closer to your answer.
SQL Fiddle Example
Rodney's muli-pivot is clever, that's for sure. Here are two other alternatives that are of course less appealing when you get into the 10X vs. 3X area.
;WITH a AS
(
SELECT Id, Value, Type, Status,
n = ROW_NUMBER() OVER (PARTITION BY Id ORDER BY [Status], [Type])
FROM dbo.MyTable
)
SELECT a.Id,
Value1 = a.Value, Type1 = a.[Type], Status1 = a.[Status],
Value2 = b.Value, Type2 = b.[Type], Status2 = b.[Status],
Value3 = c.Value, Type3 = c.[Type], Status3 = c.[Status]
FROM a
OUTER APPLY (SELECT * FROM a AS T2 WHERE n = a.n + 1 AND id = a.id) AS b
OUTER APPLY (SELECT * FROM a AS T2 WHERE n = b.n + 1 AND id = b.id) AS c
WHERE a.n = 1
ORDER BY a.Id;
-- or --
;WITH a AS
(
SELECT Id, Value, [Type], [Status],
n = ROW_NUMBER() OVER (PARTITION BY Id ORDER BY [Status], [Type])
FROM dbo.MyTable
)
SELECT Id,
Value1 = MAX(CASE WHEN n = 1 THEN Value END),
Type1 = MAX(CASE WHEN n = 1 THEN [Type] END),
Status1 = MAX(CASE WHEN n = 1 THEN [Status] END),
Value2 = MAX(CASE WHEN n = 2 THEN Value END),
Type2 = MAX(CASE WHEN n = 2 THEN [Type] END),
Status2 = MAX(CASE WHEN n = 2 THEN [Status] END),
Value3 = MAX(CASE WHEN n = 3 THEN Value END),
Type3 = MAX(CASE WHEN n = 3 THEN [Type] END),
Status3 = MAX(CASE WHEN n = 3 THEN [Status] END)
FROM a
GROUP BY Id
ORDER BY a.Id;
This might work for you, though it's not elegant.
select aa.FK_Id
, isnull(max(aa.Value1), '') as Value1
, isnull(max(aa.Type1), '') as Type1
, isnull(max(aa.Status1), '') as Status1
, isnull(max(aa.Value2), '') as Value2
, isnull(max(aa.Type2), '') as Type2
, isnull(max(aa.Status2), '') as Status2
, isnull(max(aa.Value3), '') as Value3
, isnull(max(aa.Type3), '') as Type3
, isnull(max(aa.Status3), '') as Status3
from
(
select FK_Id
, case when RowNumber = 1 then Value else null end as Value1
, case when RowNumber = 1 then [Type] else null end as Type1
, case when RowNumber = 1 then [Status] else null end as Status1
, case when RowNumber = 2 then Value else null end as Value2
, case when RowNumber = 2 then [Type] else null end as Type2
, case when RowNumber = 2 then [Status] else null end as Status2
, case when RowNumber = 3 then Value else null end as Value3
, case when RowNumber = 3 then [Type] else null end as Type3
, case when RowNumber = 3 then [Status] else null end as Status3
from Table1
) aa
group by aa.FK_Id
try something like this:
declare #rowCount int
set #rowCount = 10
declare #isNullClause varchar(4024)
set #isnullClause = ''
declare #caseClause varchar(4024)
set #caseClause = ''
declare #i int
set #i = 1
while(#i <= #rowCount) begin
set #isnullClause = #isNullClause +
' , max(aa.Value' + CAST(#i as varchar(3)) + ') as Value' + CAST(#i as varchar(3)) +
' , max(aa.Type' + CAST(#i as varchar(3)) + ') as Type' + CAST(#i as varchar(3)) +
' , max(aa.Status' + CAST(#i as varchar(3)) + ') as Status' + CAST(#i as varchar(3)) + ' ';
set #caseClause = #caseClause +
' , case when RowNumber = ' + CAST(#i as varchar(3)) + ' then Value else null end as Value' + CAST(#i as varchar(3)) +
' , case when RowNumber = ' + CAST(#i as varchar(3)) + ' then Type else null end as Type' + CAST(#i as varchar(3)) +
' , case when RowNumber = ' + CAST(#i as varchar(3)) + ' then Status else null end as Status' + CAST(#i as varchar(3)) + ' '
set #i = #i + 1;
end
declare #sql nvarchar(4000)
set #sql = 'select aa.FK_Id ' + #isnullClause + ' from ( select FK_Id '
+ #caseClause + ' from Table1) aa group by aa.FK_Id '
exec SP_EXECUTESQL #sql