Row and column total in dynamic pivot with multiple Select column - sql

In SQL Server 2008, I have a table tblStock with 4 columns:
PartCode (NVARCHAR (50))
Role (NVarchar(10))
StockQty (INT)
Location (NVARCHAR(50))
Some example data below:
I have written this code to get the following output:
IF OBJECT_ID('tempdb..#tblData') IS NOT NULL
DROP TABLE #tblData
SELECT *
INTO #tblData
FROM
(SELECT 'A' PartCode, 'Manager' As [Role], 10 StockQty, 'in-A' Location
UNION ALL
SELECT 'B', 'Director' As [Role], 22, 'in-A'
UNION ALL
SELECT 'A', 'Director' As [Role], 1, 'in-B'
UNION ALL
SELECT 'C', 'Director' As [Role], 20, 'in-A'
UNION ALL
SELECT 'D', 'Director' As [Role], 39, 'in-F'
UNION ALL
SELECT 'E', 'Director' As [Role], 3, 'in-D'
UNION ALL
SELECT 'F', 'Director' As [Role], 7, 'in-A'
UNION ALL
SELECT 'A', 'Director' As [Role], 9, 'in-C'
UNION ALL
SELECT 'D', 'Director' As [Role], 2, 'in-A'
UNION ALL
SELECT 'F', 'Director' As [Role], 54, 'in-E') TAB
SELECT *
FROM #tblData
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + Location + ']', '[' + Location + ']')
FROM (SELECT DISTINCT Location FROM #tblData) PV
ORDER BY Location
SELECT #cols += ',[Total]'
DECLARE #NulltoZeroCols NVARCHAR (MAX)
SELECT #NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']'
FROM (SELECT DISTINCT Location FROM #tblData)TAB
ORDER BY Location FOR XML PATH('')),2,8000)
SELECT #NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT PartCode, Role, ' + #NulltoZeroCols + ' FROM
(
SELECT
ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode,
Role,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData
GROUP BY Location,PartCode,Role
WITH CUBE
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + #cols + ')
) p
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode'
EXEC SP_EXECUTESQL #query
Result for the above query is:
I want to get the result like this:
Please share your ideas - thanks!

Not MIN, use SUM. Also, you should not select the Role column.
Try this;
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + Location + ']', '[' + Location + ']')
FROM (SELECT DISTINCT Location FROM #tblData) PV
ORDER BY Location
SELECT #cols += ',[Total]'
DECLARE #NulltoZeroCols NVARCHAR (MAX)
SELECT #NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']'
FROM (SELECT DISTINCT Location FROM #tblData)TAB
ORDER BY Location FOR XML PATH('')),2,8000)
DECLARE #SumCols NVARCHAR (MAX)
SELECT #SumCols = SUBSTRING((SELECT '+(ISNULL(['+Location+'],0))'
FROM (SELECT DISTINCT Location FROM #tblData)TAB
ORDER BY Location FOR XML PATH('')),2,8000)
PRINT #SumCols
SET #SumCols += ') AS [Total]'
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT PartCode, (SELECT TOP 1 Role FROM #tblData WHERE PartCode=p.PartCode) Role, ' + #NulltoZeroCols +', ('+ #SumCols+' FROM
(
SELECT
ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData
GROUP BY Location,PartCode
WITH CUBE
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + #cols + ')
) p
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode'
PRINT #query
EXEC SP_EXECUTESQL #query

Updated part will be,
SET #query = 'SELECT PartCode, Role, ' + #NulltoZeroCols + ' FROM
(
SELECT PartCode, Role, StockQty, Location
FROM #tblData
UNION ALL
SELECT PartCode, Role, SUM(StockQty), ''Total'' as Location
FROM #tblData
GROUP BY PartCode, Role
UNION ALL
SELECT
''Total'' PartCode,
''Total'' Role,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData
GROUP BY Location
WITH cube
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + #cols + ')
) p
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode'

DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT p.PartCode, (SELECT TOP 1 Role FROM #tblData t3 WHERE t3.PartCode = p.PartCode and t3.Role = t2.Role ) Role, ' + #NullToZeroCols +', ('+ #SumCols+' FROM
(
SELECT
ISNULL(CAST(t1.PartCode AS VARCHAR(30)),''Total'')PartCode,
-- Role,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData t1
GROUP BY Location,t1.PartCode
WITH CUBE
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + #cols + ')
) p
left JOIN #tblData t2 on t2.PartCode = p.PartCode
GROUP BY t2.Role,p.PartCode, ' + #cols +'
ORDER BY CASE WHEN (p.PartCode=''Total'') THEN 1 ELSE 0 END,p.PartCode'
PRINT #query
EXEC (#query)

Related

Splicing SQL display Chinese characters problem

I have following SQL script which I hope to cross apply to select Chinese column name
CREATE TABLE #temp([color] varchar(5), [size] varchar(5),[AQty] varchar(10),[BQty] varchar(10),[CQty] varchar(10),[DQty] varchar(10));
INSERT INTO #temp([color], [size], [AQty], [BQty],[CQty],[DQty])
VALUES ('A1', 'L','1','2','3','4')
, ('A1', 'M','1','2','3','4')
, ('A1', 'S','1','2','3','4')
, ('A1', 'XL','1','2','3','4')
, ('B1', 'L','1','2','3','4')
, ('B1', 'M','1','2','3','4')
, ('B1', 'S','1','2','3','4')
, ('B1', 'XL','1','2','3','4')
, ('B1', 'XXL','1','2','3','4')
, ('C1', 'L','1','2','3','4')
, ('C1', 'S','1','2','3','4')
declare #cols as varchar(max), #sql varchar(max)
select #cols = STRING_AGG(col, ', ') from (
select distinct QUOTENAME(size) as col from #temp
) as t
set #sql = '
select color, col as total, ' + #cols + '
from(
select color, size, col, [value]
from #temp
cross apply (
select ''总数一'', cast(AQty as varchar(10)) union all
select ''总数二'', cast(BQty as varchar(10)) union all
select ''总数三'', cast(CQty as varchar(10)) union all
select ''总数四'', cast(DQty as varchar(10))
) c(col, [value])
) d
pivot
(
max(value)
for size in (' + #cols + ')
) piv
order by color, total
'
exec(#sql)
But now exec SQL is display garbled when I hope to display Chinese column name
color total L M S XL XXL
A1 ??? 4 4 4 4 NULL
B1 ??? 4 4 4 4 4
C1 ??? 4 NULL4 NULLNULL
I tried to change it like this, change variable nvarchar, set #sql with N and change cross apply select with N, but now not work.
declare #cols as nvarchar(max), #sql nvarchar(max)
set #sql = N'
select color, col as total, ' + #cols + '
from(
select color, size, col, [value]
from #temp
cross apply (
select N''总数一'', cast(AQty as varchar(10)) union all
select N''总数二'', cast(BQty as varchar(10)) union all
select N''总数三'', cast(CQty as varchar(10)) union all
select N''总数四'', cast(DQty as varchar(10))
) c(col, [value])
) d
pivot
(
max(value)
for size in (' + #cols + ')
) piv
order by color, total
'
exec(#sql)
I have solved my problem by adding N after + #cols +
declare #cols as nvarchar(max), #sql nvarchar(max)
set #sql = N'
select color, col as total, ' + #cols + N'
from(
select color, size, col, [value]
from #temp
cross apply (
select N''总数一'', cast(AQty as varchar(10)) union all
select N''总数二'', cast(BQty as varchar(10)) union all
select N''总数三'', cast(CQty as varchar(10)) union all
select N''总数四'', cast(DQty as varchar(10))
) c(col, [value])
) d
pivot
(
max(value)
for size in (' + #cols + ')
) piv
order by color, total
'
exec(#sql)

Interchange row and column

I have shared sample query and expected result. My queried result is like
Query for this
select *
into #res
from (
select 'B1' branch,123 amount,2 count,1234 Total
union all
select 'B2' branch,523 amount,23 count,123 Total
union all
select 'B3' branch,666 amount,9 count,652 Total
union all
select 'B4' branch,234 amount,12 count,256 Total
) res
select * from #res
Expected Result Image
I tried using pivot but I didn't get.
if only your branch is dynamic, you can union the amount, count and total.
select * into #res from (
select 'B1' branch,123 amount,2 count,1234 Total
union all
select 'B2' branch,523 amount,23 count,123 Total
union all
select 'B3' branch,666 amount,9 count,652 Total
union all
select 'B4' branch,234 amount,12 count,256 Total
union all
select 'B5' branch,233 amount,12 count,256 Total
)res
declare #cols nvarchar(max);
declare #sql nvarchar(max);
select #cols =
stuff((select N'],[' + branch
from (select branch
from #res) AS t1
for xml path('')
), 1, 2, '') + N']';
set #sql = N'Select ''desc'' as [desc], ' + #cols + N'
from (select branch from #res)t1
pivot
(
max(t1.branch)
for t1.branch in (' + #cols + N')
) p
union all
Select ''amount'' as [desc], ' + #cols + N'
from (select cast(amount as varchar(30)) as amount, branch from #res)t1
pivot
(
max(t1.amount)
for t1.branch in (' + #cols + N')
) p
union all
Select ''count'' , ' + #cols + N'
from (select cast([count] as varchar(30)) as [count], branch from #res)t1
pivot
(
max(t1.[count])
for t1.branch in (' + #cols + N')
) p
union all
Select ''Total'' , ' + #cols + N'
from (select cast([Total] as varchar(30)) as [Total], branch from #res)t1
pivot
(
max(t1.[Total])
for t1.branch in (' + #cols + N')
) p
'
print #sql;
exec sp_executesql #sql;
drop table #res

Query to pivot in SQL

I have data in the following format:
I need to pivot this to get the data as follows.
Please help!!!
Something like this. In this case you need to have a fixed list of names.
SELECT
SUM(CASE WHEN Student='Mike' THEN [English Mark] ELSE 0 END) as [Mike English Mark],
SUM(CASE WHEN Student='Mike' THEN [Maths Mark] ELSE 0 END) as [Mike Maths Mark],
SUM(CASE WHEN Student='Fisher' THEN [English Mark] ELSE 0 END) as [Fisher English Mark],
SUM(CASE WHEN Student='Fisher' THEN [Maths Mark] ELSE 0 END) as [Fisher Maths Mark],
SUM(CASE WHEN Student='John' THEN [English Mark] ELSE 0 END) as [John English Mark],
SUM(CASE WHEN Student='John' THEN [Maths Mark] ELSE 0 END) as [John Maths Mark],
[TestName]
FROM Table1
GROUP BY [Test Name]
The solution I got is a bit tricky but very dynamic.
You should first unpivot your table, and put the data in a temp table, after that I get the columns name for the pivoting and put the result in the #cols variable. At the end I create a dynamic sql string to pivot the the temp table that contains my data, so even if a new student gets added to the table his 2 columns will be generated in the end result.
select test, col + ' '+ Student stu_col , value
INTO
#temp
from Marks
unpivot(value for col in (english, maths)) unpiv
DECLARE #cols AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(stu_col)
from #temp order by 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT test, ' + #cols + ' from
(
select test, Value, stu_col
from #temp
) x
pivot
(
SUM(Value)
for stu_col in (' + #cols + ')
) p '
exec(#query)
DROP TABLE #temp
You can write a dynamic sql query using Pivot operator as:
DECLARE #columns NVARCHAR(MAX)
,#columnsEnglish_Mark NVARCHAR(MAX)
,#columnsMath_Mark NVARCHAR(MAX)
,#columnsFNL NVARCHAR(MAX)
,#sql NVARCHAR(MAX);
SET #columns = N'';
--Get column names for entire pivoting
SELECT #columns += N', ' + QUOTENAME(SpreadCol)
FROM (select distinct student as SpreadCol
from tblstudent
) AS T;
PRINT #columns;
--Get column names for Pivot1
SET #columnsEnglish_Mark = N'';
SELECT #columnsEnglish_Mark += N', ISNULL(' + QUOTENAME(SpreadCol) + ',0) AS [' + SpreadCol + '_English_Mark]'
FROM (select distinct student as SpreadCol
from tblstudent
) AS T
;
PRINT #columnsEnglish_Mark;
--Get column names for Pivot2
SET #columnsMath_Mark = N'';
SELECT #columnsMath_Mark += N', ISNULL(' + QUOTENAME(SpreadCol) + ',0) AS [' + SpreadCol + '_Math_Mark]'
FROM (select distinct student as SpreadCol
from tblstudent
) AS T
;
PRINT #columnsMath_Mark;
--Get final list of columns:
SET #columnsFNL = N'';
SELECT #columnsFNL += N', [' + SpreadCol + '_English_Mark], [' + SpreadCol + '_Math_Mark] '
FROM (select distinct student as SpreadCol
from tblstudent
) AS T
order by T.SpreadCol asc; -- change ordering of columns here
PRINT #columnsFNL;
SET #sql = N'
select tblEnglish_Mark.Test_Name , ' + STUFF(#columnsFNL, 1, 2, '') + ' from
'
+
'
( SELECT Test_Name, ' + STUFF(#columnsEnglish_Mark, 1, 2, '') + '
FROM
(select student as SpreadCol , English_Mark, Test_Name
from tblstudent ) as D
PIVOT
(
sum(English_Mark) FOR SpreadCol IN ('
+ STUFF(REPLACE(#columns, ', [', ',['), 1, 1, '')
+ ')
) AS Pivot1 ) tblEnglish_Mark
inner join
'
+
'
( SELECT Test_Name, ' + STUFF(#columnsMath_Mark, 1, 2, '') + '
FROM
(select student as SpreadCol , Test_Name,Math_Mark
from tblstudent ) as D
PIVOT
(
MAx(Math_Mark) FOR SpreadCol IN ('
+ STUFF(REPLACE(#columns, ', [', ',['), 1, 1, '')
+ ')
) as Pivot2 ) tblMath_Mark
on tblEnglish_Mark.Test_Name = tblMath_Mark.Test_Name ;
'
;
PRINT #sql;
EXEC sp_executesql #sql;
Hope this helps!!!
Please try:
DECLARE #pivv NVARCHAR(MAX),#Query NVARCHAR(MAX)
SELECT #pivv=COALESCE(#pivv+',','')+ QUOTENAME(Student+'_English_Mark')+','+QUOTENAME(Student+'_Maths_Mark')
FROM YourTable GROUP BY Student
IF ISNULL(#pivv, '')<>''
SET #Query='SELECT* FROM(
select English_Mark Marks, Student+''_English_Mark'' Col, Test_Name From YourTable
union all
select Maths_Mark Marks, Student+''_Maths_Mark'' Col, Test_Name From YourTable
)x pivot (sum(Marks) for Col in ('+#pivv+')) as xx'
IF ISNULL(#Query, '')<>''
EXEC (#Query)
SQL Fiddle Demo

T-SQL Pivot - Total Row and Dynamic Columns

Let's jump straight into it. Here's the code
SELECT [prov], [201304], [201305], [201306], [201307]
FROM (
SELECT [prov], [arrival], [Amount]
FROM [tblSource]) up
PIVOT (SUM([Amount]) FOR [arrival] IN ([201304], [201305], [201306], [201307])) AS pvt
GO
It brings me back an ever so lovely table. I was wondering how I would get the totals for each "date" column to show in an appended last row?
In addition, the underlying table will have more data added, specifically more dates. This means that 201308 will be added next, then 201309 etc
This will mean that currently I will have to amend the code above each month to reflect the addition. Is there anyway around this?
You can dynamically create the columns using dynamic SQL, however, I would really recommend handling dynamic pivots in a layer designed for it, such as SSRS or excel.
DECLARE #SQL NVARCHAR(MAX) = '',
#SQL2 NVARCHAR(MAX) = '',
#SQL3 NVARCHAR(MAX) = '';
-- COMPILE THE UNIQUE VALUES FOR ARRIVAL THAT NEED TO BE PIVOTED
SELECT #SQL = #SQL + ',' + QUOTENAME(Arrival),
#SQL2 = #SQL2 + '+ISNULL(' + QUOTENAME(Arrival) + ', 0)',
#SQL3 = #SQL3 + ',' + QUOTENAME(Arrival) + ' = ISNULL(' + QUOTENAME(Arrival) + ', 0)'
FROM (SELECT DISTINCT Arrival FROM tblSource) s;
-- COMBINE THEM INTO A SINGLE QUERY
SET #SQL = 'SELECT [Prov]' + #SQL3 + ', [Total] = ' + STUFF(#SQL2, 1, 1, '') + '
FROM ( SELECT Arrival, Prov, Amount
FROM [tblSource]
UNION ALL
SELECT Arrival, ''Total'', SUM(Amount)
FROM [tblSource]
GROUP BY Arrival
) up
PIVOT
( SUM(Amount)
FOR Arrival IN (' + STUFF(#SQL, 1, 1, '') + ')
) pvt;';
-- EXECUTE THE QUERY
EXECUTE SP_EXECUTESQL #SQL;
This creates and executes the following SQL:
SELECT [Prov],
[2013-01-01] = ISNULL([2013-01-01], 0),
[2013-02-01] = ISNULL([2013-02-01], 0),
[Total] = ISNULL([2013-01-01], 0) + ISNULL([2013-02-01], 0)
FROM ( SELECT Arrival, Prov, Amount
FROM [tblSource]
UNION ALL
SELECT Arrival, 'Total', SUM(Amount)
FROM [tblSource]
GROUP BY Arrival
) up
PIVOT
( SUM(Amount)
FOR Arrival IN ([2013-01-01],[2013-02-01])
) pvt;
It is the query below union in the subquery up that adds the total row at the bottom, and the row total is simply created by adding all the columns in the row.
Example on SQL Fiddle
I will stress again though, I really recommend handling manipulation of data like this outside of SQL.
EDIT
An alternative to using the UNION to get the the total row is to use GROUPING SETS as follows:
DECLARE #SQL NVARCHAR(MAX) = '',
#SQL2 NVARCHAR(MAX) = '',
#SQL3 NVARCHAR(MAX) = '';
-- COMPILE THE UNIQUE VALUES FOR ARRIVAL THAT NEED TO BE PIVOTED
SELECT #SQL = #SQL + ',' + QUOTENAME(Arrival),
#SQL2 = #SQL2 + '+ISNULL(' + QUOTENAME(Arrival) + ', 0)',
#SQL3 = #SQL3 + ',' + QUOTENAME(Arrival) + ' = ISNULL(' + QUOTENAME(Arrival) + ', 0)'
FROM (SELECT DISTINCT Arrival FROM tblSource) s;
-- COMBINE THEM INTO A SINGLE QUERY
SET #SQL = 'SELECT [Prov]' + #SQL3 + ', [Total] = ' + STUFF(#SQL2, 1, 1, '') + '
FROM ( SELECT Arrival, Prov = ISNULL(Prov, 'Total'), Amount = SUM(Amount)
FROM [tblSource]
GROUP BY GROUPING SETS((Prov, arrival), (arrival))
) up
PIVOT
( SUM(Amount)
FOR Arrival IN (' + STUFF(#SQL, 1, 1, '') + ')
) pvt;';
-- EXECUTE THE QUERY
EXECUTE SP_EXECUTESQL #SQL;
SAMPLE TABLE
CREATE TABLE #TEMP([prov] VARCHAR(100),[arrival] INT, AMOUNT NUMERIC(12,2))
INSERT INTO #TEMP
SELECT 'A' [prov],'201304' [arrival],100 AMOUNT
UNION ALL
SELECT 'A' ,'201305' ,124
UNION ALL
SELECT 'A' ,'201306' ,156
UNION ALL
SELECT 'B' ,'201304' ,67
UNION ALL
SELECT 'B' ,'201305' ,211
UNION ALL
SELECT 'B' ,'201306' ,176
UNION ALL
SELECT 'C' ,'201304' ,43
UNION ALL
SELECT 'C' ,'201305' ,56
UNION ALL
SELECT 'C' ,'201306' ,158
QUERY
You can use ROLLUP to get the row total. More about ROLLUP here
-- Get the columns for dynamic pivot
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + CAST([arrival] AS VARCHAR(50)) + ']',
'[' + CAST([arrival] AS VARCHAR(50)) + ']')
FROM (SELECT DISTINCT [arrival] FROM #TEMP) PV
ORDER BY [arrival]
-- Replace NULL value with zero
DECLARE #NulltoZeroCols NVARCHAR (MAX)
SELECT #NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+[arrival]+'],0) AS ['+[arrival]+']'
FROM (SELECT DISTINCT CAST([arrival] AS VARCHAR(50)) [arrival] FROM #TEMP)TAB
ORDER BY CAST([arrival]AS INT) FOR XML PATH('')),2,8000)
DECLARE #query NVARCHAR(MAX)
SET #query = 'SELECT [prov],' + #NullToZeroCols + ' FROM
(
SELECT
ISNULL([prov],''Total'')[prov],
SUM(AMOUNT)AMOUNT ,
ISNULL(CAST([arrival] AS VARCHAR(50)),''Total'')[arrival]
FROM #TEMP
GROUP BY [arrival],[prov]
WITH ROLLUP
) x
PIVOT
(
MIN(AMOUNT)
FOR [arrival] IN (' + #cols + ')
) p
ORDER BY CASE WHEN ([prov]=''Total'') THEN 1 ELSE 0 END,[prov]'
EXEC SP_EXECUTESQL #query
Note : If you do not want to replace NULL with zero, just replace #NullToZeroCols with #cols in outer query of dynamic pivot

Flattening a Single Table

I am looking for a very basic flattening. I have a table in the database which provides each field for the employee in a different row.
EX
EMPLOYEE GROUP_NAME
81 BNEEO55
81 BNELLIG
81 LPKAPE
81 HRFT
90 BNRETINV
....
I would like to create a view which reports the data as:
EMPLOYEE Group1 Group2 Group3 Group4 Group5
81 BNEEO55 BNELLIG LPKAPE HRFT NULL
90 NULL NULL NULL NULL BNRETINV
OR
EMPLOYEE BNEEO55 BNELLIG LPKAPE HRFT BNRETINV
81 YES YES YES YES NO
90 NO NO NO NO YES
You need to PIVOT the data, if you are using SQL-Server 2008 or later you can use the PIVOT function:
CREATE TABLE #T (Employee INT, Group_name VARCHAR(50))
INSERT #T VALUES (81, 'BNEEO55'), (81, 'BNELLIG'), (81, 'LPKAPE'), (81, 'HRFT'), (90, 'BNRETINV')
SELECT Employee,
COALESCE([BNEEO55],'No') AS [BNEEO55],
COALESCE([BNELLIG],'No') AS [BNELLIG],
COALESCE([BNRETINV],'No') AS [BNRETINV],
COALESCE([HRFT],'No') AS [HRFT],
COALESCE([LPKAPE],'No') AS [LPKAPE]
FROM ( SELECT *, 'Yes' [Data]
FROM #T
) d
PIVOT
( MAX(Data)
FOR Group_Name IN ([BNEEO55], [BNELLIG], [BNRETINV], [HRFT], [LPKAPE])
) pvt
But it sounds like you need to do it dynamically if your data is changing. Something like the following would work:
DECLARE #SQL NVARCHAR(MAX) = '',
#Cols NVARCHAR(MAX) = ''
SELECT #SQL = #SQL + ',' + QUOTENAME(Group_Name),
#Cols = #Cols + ',COALESCE(' + QUOTENAME(Group_Name) + ',''No'') AS ' + QUOTENAME(Group_Name)
FROM ( SELECT DISTINCT Group_Name
FROM #T
) T
SET #SQL = '
SELECT Employee, ' + STUFF(#Cols, 1, 1, '') +
'FROM ( SELECT *, ''Yes'' [Data]
FROM #T
) d
PIVOT
( MAX(Data)
FOR Group_Name IN (' + STUFF(#SQL, 1, 1, '') + ')
) pvt'
EXECUTE SP_EXECUTESQL #SQL
This builds up the same query as the first one, but means that when a new group name is added the query doesn't have to be altered.
EDIT
To create and call this as a stored procedure:
CREATE TABLE T (Employee INT, Group_name VARCHAR(50))
INSERT T VALUES (81, 'BNEEO55'), (81, 'BNELLIG'), (81, 'LPKAPE'), (81, 'HRFT'), (90, 'BNRETINV')
GO
CREATE PROCEDURE PivotT
AS
DECLARE #SQL NVARCHAR(MAX) = '',
#Cols NVARCHAR(MAX) = ''
SELECT #SQL = #SQL + ',' + QUOTENAME(Group_Name),
#Cols = #Cols + ',COALESCE(' + QUOTENAME(Group_Name) + ',''No'') AS ' + QUOTENAME(Group_Name)
FROM ( SELECT DISTINCT Group_Name
FROM T
) T
SET #SQL = '
SELECT Employee, ' + STUFF(#Cols, 1, 1, '') +
'FROM ( SELECT *, ''Yes'' [Data]
FROM T
) d
PIVOT
( MAX(Data)
FOR Group_Name IN (' + STUFF(#SQL, 1, 1, '') + ')
) pvt'
EXECUTE SP_EXECUTESQL #SQL
GO
EXECUTE PivotT