2013-09-19 4 views
1

У меня есть эта таблица:Получение PIVOT с помощью GroupBy

Person  Job  Day EndDay 
1   101  1 12 
1   102  2 11 
1   103  3 11 
3   101  1 11 
3   102  2 11 
3   JobOff 3 11 
2   101  1 11 
2   102  2 11 
2   103  3 11 
2   JobOff 4 11 
... 

PS: Мои дни ДО 'N', который я не знаю. Таким образом, статический SQL здесь невозможен.

И мне нужно, чтобы изменить его к этой форме:

Day (Columns) 
Person (Rows) 
Person 1 2 3  4 
1  101 102 103  N/A 
2  101 102 103  JobOff 
3  101 102 JobOff N/A 

Любая помощь будет оценена. Я очень новичок в SQL.

Благодаря Roman, у меня есть S.Procedure:

CREATE PROCEDURE [dbo].[MyStoredProcedure] AS 
BEGIN 

declare @stmt nvarchar(max) 

select @stmt = 
    isnull(@stmt + ', ', '') + 
    'isnull(max(case when [Day] = ' + cast([Day_I] as nvarchar(max)) + 
    ' then Job end), ''N/A'') as [' + cast([Day_I] as nvarchar(max)) + ']' 
from (select distinct [Day_I] from dbo.Solution) as t 
order by [Day_I] 

select @stmt = ' 
select 
    Person_I, ' + @stmt +' 
from dbo.Solution_Format 
group by Person_I' 

END 

Но когда я выполнения этой хранимой процедуры, как это:

exec MyStoredProcedure 

Его не показывал мне никаких результатов. Нет ошибок!

ответ

3
select 
    Person, 
    isnull(max(case when [Day] = 1 then Job end), 'N/A') as [1], 
    isnull(max(case when [Day] = 2 then Job end), 'N/A') as [2], 
    isnull(max(case when [Day] = 3 then Job end), 'N/A') as [3], 
    isnull(max(case when [Day] = 4 then Job end), 'N/A') as [4] 
from Table1 
group by Person 

sql fiddle demo

это также можно сделать с помощью динамического SQL, если вам это необходимо для произвольного числа колонок:

create procedure [dbo].[MyStoredProcedure] 
as 
begin 
    declare @stmt nvarchar(max) 

    select @stmt = 
     isnull(@stmt + ', ', '') + 
     'isnull(max(case when [Day] = ' + cast([Day] as nvarchar(max)) + 
     ' then Job end), ''N/A'') as [' + cast([Day] as nvarchar(max)) + ']' 
    from (select distinct [Day] from Table1) as t 
    order by [Day] 

    select @stmt = ' 
    select 
     Person, ' + @stmt +' 
    from Table1 
    group by Person' 

    exec sp_executesql 
     @stmt = @stmt 
end 

sql fiddle demo

+0

Nice Dynamic sample –

+0

Спасибо! Однако мои дни (столбцы) до 63. Будет ли ваше динамическое решение работать? –

+0

@ RG-3 он должен работать на любое количество отдельных дней, попробуйте его –

2

Один из способов сделать это, чтобы использовать несколько самостоятельно присоединяется

Select 
    t1.Person, 
    COALESCE(t1.Job, 'N/A') [1], 
    COALESCE(t2.Job, 'N/A')[2], 
    COALESCE(t3.Job, 'N/A') [3], 
    COALESCE(t4.Job, 'N/A') [4] 
FROM 
    table1 t1 
    LEFT JOIN table1 t2 
    ON t1.Person = t2.Person 
    and t2.Day = 2 
    LEFT JOIN table1 t3 
    ON t1.Person = t3.Person 
    and t3.Day = 3 
    LEFT JOIN table1 t4 
    ON t1.Person = t4.Person 
    and t4.Day = 4 
WHERE 
    t1.Day = 1 
ORDER BY 
    t1.Person 

DEMO

Другое способов является использование MAX (СЛУЧАЙ однако я не поклонник использования агрегатов, как это.

Select 
    t1.Person, 
    COALESCE(MAX(CASE WHEN t1.Day = 1 then t1.Job END), 'N/A') [1], 
    COALESCE(MAX(CASE WHEN t1.Day = 2 then t1.Job END), 'N/A') [2], 
    COALESCE(MAX(CASE WHEN t1.Day = 3 then t1.Job END), 'N/A') [3], 
    COALESCE(MAX(CASE WHEN t1.Day = 4 then t1.Job END), 'N/A') [4] 

FROM 
    table1 t1 
GROUP BY 
    t1.Person 

DEMO

И, наконец, есть т он повернуть положение, которое я не очень нравится из-за MAX здесь

SELECT person, 
     COALESCE([1], 'N/A') [1], 
     COALESCE([2], 'N/A') [2], 
     COALESCE([3], 'N/A') [3], 
     COALESCE([4], 'N/A') [4] 
FROM (SELECT t1.person, 
       t1.day, 
       t1.job 
     FROM table1 t1) p 
     PIVOT (Max (job) 
      FOR day IN ([1], 
          [2], 
          [3], 
          [4])) AS pvt 

DEMO

+0

+1 несколько решений –

+0

Мои дни (колонны) являются до 63 или больше ... Если я двигаюсь вперед таким образом, что это будет много строк кода. –

+0

@ RG-3 Ну, вы можете легко сгенерировать инструкцию SQL. Независимо от того, генерируется ли он во время выполнения, не должно быть основано на ваших требованиях. –

Смежные вопросы