2012-04-16 13 views
2

У меня есть запрос, который извлекает все агенты и их модули, результирующий набор возвращает 1 строку на модуль.SQL Server PIVOT Function

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 является возвращение ниже

 
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() в этой колонке. Результат будет 1 или null. Используйте 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 

Если вы хотите построить это динамически вам нужно сначала сделать запрос, который возвращает модули, которые имеют в результате, а затем вы должны использовать, чтобы построить динамический оператор. Вероятно, вам лучше сохранить результат из вашего запроса в таблице temp, а затем использовать эту таблицу при построении динамического запроса.

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