2012-04-16 114 views
2

我有一个查询检索所有代理和他们的模块,结果集将返回每个模块1行。SQL Server PIVOT函数

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 

数据集是回报率低于

 
agentid | agentdisplayname | modulename 
94  | Agent1   | Module 1 
94  | Agent1   | Module 2 
94  | Agent1   | Module 3 
23  | Agent1   | Module 2 
23  | Agent1   | Module 3 

我想使用PIVOT函数返回一个表,看起来更像

 
agentid | agentdisplayname | Module 1 | Module 2 | Module 3 |.. .. .. 
94  | Agent1   | 1   | 1   | 1 
23  | Agent2   | 0   | 1   | 1 

有模块的动态列表,以便我无法在查询中对它们进行硬编码。我已经试过PICOT,但它似乎期待一个聚合函数,并不太确定这是我需要的这种情况。

回答

3

您可以为结果添加一个额外的列,并在该列上使用min()。结果将是1null。使用isnull可获得0而不是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 

如果要动态地建立这一点,你需要先做返回你的结果,然后你需要用它来构建动态声明模块的查询。您最好将查询结果存储在临时表中,然后在构建动态查询时使用该表。

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 

使用#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'[email protected]+ 
    'from (select agentid, agentdisplayname, modulename, 1 as dummy 
     from YourTable) as T 
    pivot (min(dummy) for modulename in ('[email protected]+')) as P' 

exec sp_executesql @SQL 

drop table #Tmp