2012-04-16 166 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