I have a query that retrieves all agents and thier modules, the result set will return 1 row per module.
SELECT
am.agentID AS agentid,
pa.agentDisplayName agentdisplayname,
m.ModuleName ModuleName
FROM
AgentModule AS am
JOIN primaryagent AS pa
ON am.agentID = pa.AgentID
JOIN Module AS m
ON am.ModuleID = m.ModuleID
WHERE
m. Active = 1
AND pa.groupID = 75
Dataset is return as below
agentid | agentdisplayname | modulename
94 | Agent1 | Module 1
94 | Agent1 | Module 2
94 | Agent1 | Module 3
23 | Agent1 | Module 2
23 | Agent1 | Module 3
I am trying to use the PIVOT function to return a table that looks more like
agentid | agentdisplayname | Module 1 | Module 2 | Module 3 |.. .. ..
94 | Agent1 | 1 | 1 | 1
23 | Agent2 | 0 | 1 | 1
There are a dynamic list of modules so I cannot hard code them in the query. I have tried PICOT but it seems to expect an aggregate function and not quite sure it is what I would need for this scenario.
You can add a extra column to you result and use min() on that column. The result will be 1
or null
. Use isnull
to get a 0
instead of null
.
select agentid,
agentdisplayname,
isnull([Module 1], 0) as [Module 1],
isnull([Module 2], 0) as [Module 2],
isnull([Module 3], 0) as [Module 3]
from
(
select agentid, agentdisplayname, modulename, 1 as dummy
from YourResultset
) as T
pivot
(min(dummy) for modulename in ([Module 1],[Module 2],[Module 3])) as P
If you want to build this dynamically you need to first do a query that returns the modules you have in the result and then you need to use that to build the dynamic statement. It is probably best for you to store the result from your query in a temp table and then use that table when you build your dynamic query.
SELECT
am.agentID AS agentid,
pa.agentDisplayName agentdisplayname,
m.ModuleName ModuleName
INTO #Tmp
FROM
AgentModule AS am
JOIN primaryagent AS pa
ON am.agentID = pa.AgentID
JOIN Module AS m
ON am.ModuleID = m.ModuleID
WHERE
m. Active = 1
AND pa.groupID = 75
Build and run the dynamic query using #Tmp
.
declare @FieldList1 nvarchar(max)
declare @FieldList2 nvarchar(max)
declare @SQL nvarchar(max)
set @FieldList1 =
(select ',isnull('+quotename(modulename)+', 0) as '+quotename(modulename)
from #Tmp
group by modulename
order by modulename
for xml path(''), type).value('.', 'nvarchar(max)')
set @FieldList2 = stuff(
(select ','+quotename(modulename)
from #Tmp
group by modulename
order by modulename
for xml path(''), type).value('.', 'nvarchar(max)') , 1, 1, '')
set @SQL =
'select agentid, agentdisplayname'+@FieldList1+
'from (select agentid, agentdisplayname, modulename, 1 as dummy
from YourTable) as T
pivot (min(dummy) for modulename in ('+@FieldList2+')) as P'
exec sp_executesql @SQL
drop table #Tmp