Pergunta

Eu tenho um par de tabelas que esta aparência Tabela 1

user_id   |  name
-------------------------   
x111      |   Smith, James
x112      |   Smith, Jane

etc ..

A Tabela 2

id    |   code    |    date       |  incident_code    | user_id
-----------------------------------------------------------------
1     |    102008 |   10/20/2008  |    1              | x111
2     |    113008 |   11/30/2008  |    3              | x111
3     |    102008 |   10/20/2008  |    2              | x112
4     |    113008 |   11/30/2008  |    5              | x112 

O que eu gostaria de exibição é algo como isto

user_id     |    user_name    |   INCIDENT IN OCT 2008   | INCIDENT IN NOV 2008
------------------------------------------------------------------------------ 
x111        |    Smith, John  |   1                      | 3
x112        |    Smith, Jane  |   2                      | 5

etc ..

O incident_code seria substituída pela descrição real do incidente que está localizado em outra mesa, mas eu pensei que eu iria ver como isso iria funcionar em primeiro lugar.

Alguns dos cabeçalhos das colunas seria estática, enquanto outros seriam criados com base na data. Alguém um sabe como eu posso fazer isso usando o sql server 2005? Alguns exemplos seria muito útil.

Agradecemos antecipadamente

Foi útil?

Solução

Aqui está uma solução que gera e executa o SQL dinâmico, com um pivô:

DECLARE @pivot_list AS VARCHAR(MAX)

--
;
WITH    cols
          AS ( SELECT DISTINCT
                        'INCIDENT IN ' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)),
                                              3) + ' '
                        + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
               FROM     so926209_2
             )
    SELECT  @pivot_list = COALESCE(@pivot_list + ', ', '') + '[' + col + ']'
    FROM    cols

--
DECLARE @template AS VARCHAR(MAX)
SET @template = 'WITH incidents AS (
SELECT  [user_id],
        incident_code,
        ''INCIDENT IN '' + LEFT(UPPER(CONVERT(VARCHAR, [date], 107)), 3)
        + '' '' + SUBSTRING(UPPER(CONVERT(VARCHAR, [date], 107)), 9, 4) AS col
FROM    so926209_2
)
,results AS (
SELECT * FROM incidents PIVOT (MAX(incident_code) FOR col IN ({@pivot_list})) AS pvt
)
SELECT results.[user_id]
    ,so926209_1.[name]
    ,{@select_list}
FROM results INNER JOIN so926209_1 ON so926209_1.[user_id] = results.[user_id]
'

DECLARE @sql AS VARCHAR(MAX)
SET @sql = REPLACE(REPLACE(@template, '{@pivot_list}', @pivot_list), '{@select_list}', @pivot_list)

--PRINT @sql
EXEC (@sql)

Onde so926209_1, so926209_2 são sua Tabelas 1 e 2

Note que se você tiver vários incidentes em um mês para a mesma pessoa, o seu exemplo não mostra como você quer que manipulados. Este exemplo leva apenas o último incidente no mês.

Outras dicas

Isso soa como uma tarefa relatório. Elaboração de relatórios, muitas vezes referida a partir de uma perspectiva de banco de dados como OLAP, online Aanalytical Processing, tende a variar bastante freqüência de acesso ao banco "tradicional", OLTP (Online Transaction Processing) em que é muitas vezes feita de grandes agregações de dados que abrangem períodos superiores de tempo. Muito freqüentemente, o tipo de agregação a sua procura.

O uso de um Pivot como Tetraneutron sugeriu será suficiente para menores conjuntos de dados. No entanto, como o volume de dados que você precisa para informar sobre cresce, você pode precisar de algo mais avançado. OLAP está prevista no SQL Server Analysis Services (SSAS), disponível em 2005 e 2008. Usando SSAS pode criar repositórios de dados multidimensionais que os dados pré-agregados a partir de qualquer um banco de dados OLTP diretamente, ou a partir de um banco de dados de armazém de dados intermediário. dados multidimensionais (geralmente referidos como cubos), fornecem uma maneira muito mais rápida de acesso o tipo de dados que você pode obter de um pivô, sem interferir com o desempenho do seu processamento de transações padrão em seu banco de dados OLTP.

Se você tiver mais do que uma pequena quantidade de dados que você precisa para relatar, eu recomendo que você verifique SQL Server Analysis Services 2005, OLAP, cubos, e MDX (Multidimensional Extensões para T-SQL.) Há uma learnig maior curva para criar um cubo OLAP, mas uma vez que é criado, os benefícios de ter um pode ser enorme se você tem necessidades de relatórios significativos.

A consulta como isso iria funcionar:

select
    u.User_id,
    u.Name,
    Okt2008Sum = sum(case when i.date between 
        '2008-10-01' and '2008-11-01' then 1 else 0 end),
    Nov2008Sum = sum(case when i.date between 
        '2008-11-01' and '2008-12-01'then 1 else 0 end)
from #incidents i
inner join #users u on i.user_id = u.user_id
group by u.user_id, u.name

Dependendo do seu cliente e quantas vezes você tem que executá-lo, você pode gerar essa consulta. Em SQL este seria parecido com:

create table #months (
    MonthName varchar(25),
    StartDate datetime
)

insert into #months values ('Okt2008','2008-10-01')
insert into #months values ('Nov2008','2008-11-01')

declare @query varchar(8000)
select @query = 'select u.User_id, u.Name '

select @query = @query + ', ' + MonthName + 
    ' = sum(case when i.date between ''' + cast(StartDate as varchar) + 
    ''' and ''' + cast(dateadd(m,1,StartDate) as varchar) + 
    ''' then 1 else 0 end) '
from #Months

select @query = @query + '
    from #incidents i
    inner join #users u on i.user_id = u.user_id
    group by u.user_id, u.name'

exec (@query)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top