Pregunta

Tengo un par de mesas que se parecen a este Tabla 1

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

etc ..

Tabla 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 

Lo que me gustaría ver es algo como esto

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

etc ..

El incident_code sería sustituida por la descripción real del incidente que se encuentra en otra mesa, pero yo pensé que vería cómo funcionaría en primer lugar.

Algunos de los títulos de las columnas sería estática mientras que otros se crean a partir de la fecha. ¿Alguien se sabe cómo puedo hacer esto utilizando SQL Server 2005? Algunos ejemplos serían muy útiles.

Gracias de antemano

¿Fue útil?

Solución

Esta es una solución que genera y ejecuta el SQL dinámico con un pivote:

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)

Cuando so926209_1, so926209_2 son sus tablas 1 y 2

Tenga en cuenta que si tiene varios incidentes en un mes para la misma persona, su ejemplo no muestra cómo desea que manejaba. Este ejemplo sólo toma el último incidente en el mes.

Otros consejos

Esto suena como una tarea de informes. La presentación de informes, a menudo referido desde una perspectiva de base de datos como OLAP, procesamiento Aanalytical línea, tiende a variar con bastante frecuencia del acceso de base de datos "tradicional", OLTP (Online Transaction Processing), ya que muy a menudo se compone de grandes agregaciones de datos que abarcan períodos más largos de tiempo. Con bastante frecuencia, el tipo de agregación que tu buscas.

El uso de un pivote como tetraneutrón sugirió será suficiente para los conjuntos de datos más pequeños. Sin embargo, como el volumen de datos que necesita para informar sobre crece, es posible que necesite algo más avanzado. OLAP se proporciona mediante SQL Server Analysis Services (SSAS), disponible en 2005 y 2008. El uso de SSAS puede crear repositorios de datos multidimensionales que los datos pre-agregados ya sea de una base de datos OLTP directamente, o desde una base de datos de almacenamiento de datos intermediario. datos multidimensionales (generalmente conocidos como cubos), proporcionan una forma mucho más rápida para acceder al tipo de datos que se pueden obtener de un pivote, sin interferir con el rendimiento de su procesamiento de transacciones estándar en su base de datos OLTP.

Si usted tiene más de una pequeña cantidad de datos que necesita para informar sobre, le recomiendo que echa un vistazo a SQL Server Analysis Services 2005, OLAP, cubos y MDX (Extensiones multidimensionales para T-SQL). Hay un learnig más grande curva de configurar un cubo OLAP, pero una vez que se ha configurado, los beneficios de tener uno puede ser enorme si tiene importantes necesidades de información.

Una consulta como esto funcionaría:

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

En función de su cliente y con qué frecuencia hay que ejecutarlo, puede generar esta consulta. En SQL esto se vería así:

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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top