2011-05-04 19 views
6

No he visto una pregunta como esta, pero si hay alguna que haya sido respondida, por favor avíseme.Unir Múltiples Tablas Dinámicas Dinámicas

Tengo que crear una exportación, utilizando un procedimiento almacenado. Lamentablemente, en este momento, no es posible crear este informe en SSRS.

Lo que tengo que hacer es crear dinámicamente una tabla dinámica y unirla a otra, o eso es lo que pensé que funcionaría.

Los datos en bruto funciona de forma similar a esto (he cambiado los elementos a proteger los datos de mi empresa):

Data Sample

lo que quieren los datos para que parezca en el informe es la siguiente (para ahorrar espacio , No usé todas las fechas, pero puede obtener la idea): Report Sample

He creado una tabla temporal y he creado dos tablas dinámicas dinámicas. Ambas tablas funcionarán por separado, pero una vez que uso UNION ALL, recibo un mensaje de error (lo agregaré a continuación). Incluyo el código que he usado para crear los dos pivotes. ¿Puede alguien decirme qué estoy haciendo mal?

¿Es posible hacer esto en un solo pivote?

/* 
    Use dynamic SQL to find all 
    Issue Dates for column headings 
*/ 
DECLARE @Jquery VARCHAR(8000) 
DECLARE @query VARCHAR(4000) 
DECLARE @years VARCHAR(2000) 
SELECT @years = STUFF((SELECT DISTINCT 
         '],[' + 'Item 1' + ' ' + (IssueDate) 
         FROM #GroupData GroupData 
         ORDER BY '],[' + 'Item 1' + ' ' + (IssueDate) 
         FOR XML PATH('') 
         ), 1, 2, '') + ']' 

SET @query = 
'SELECT * FROM 
(
    SELECT LocationID, StoreName, StoreState AS State, "Item 1" + " " + (IssueDate) AS IssueDate, MoneyOrder 
    FROM #GroupData GroupData 
) MoneyOrderIssued 
PIVOT (MAX(MoneyOrder) FOR IssueDate 
IN ('[email protected]+')) AS pvt' 

DECLARE @queryMOUsed VARCHAR(4000) 
DECLARE @MOUsedYear VARCHAR(2000) 
SELECT @MOUsedYear = STUFF((SELECT DISTINCT 
         '],[' + 'Item 2' + ' ' + (IssueDate) 
         FROM #GroupData GroupData 
         ORDER BY '],[' + 'Item 2' + ' ' + (IssueDate) 
         FOR XML PATH('') 
         ), 1, 2, '') + ']' 

SET @queryMOUsed = 
'SELECT * FROM 
(
    SELECT LocationID, StoreName, StoreState AS State, "Item 2" + " " + (IssueDate) AS IssueDate, MOUsed 
    FROM #GroupData GroupData 
)SCRMoneyOrders 
PIVOT (MAX(MOUsed) FOR IssueDate 
IN ('[email protected]+')) AS pvt' 

SET @Jquery = @query + ' UNION ALL ' + @queryMOUsed 


EXECUTE (@query) -- Only in here to show that this works w/out UNION ALL 
EXECUTE (@queryMOUsed) -- Only in here to show that this works w/out UNION ALL 

EXECUTE (@Jquery) 

El mensaje de error que recibo es el siguiente:

Aviso: valor nulo es eliminado por una operación SET agregado o. Msg 8114, nivel 16, estado 5, línea 1 Error al convertir el tipo de datos varchar a bigint.

Respuesta

6

Mi idea es que las columnas no coinciden (en número de columnas, orden de columnas y tipo de datos). Si estoy leyendo su consulta correctamente, si las fechas de publicación para item1 y item2 no coinciden, de todos modos puede obtener columnas no coincidentes. Es realmente difícil de decir sin ver el resultado de esas dos consultas.

¿Estás seguro de que no quieres un JOIN basado en el ID de la tienda?

Algo así como:

WITH Item1Data as (
--pivot query for item 1 
), 
Item2Data as (
--pivot query for item 2 
) 
SELECT columns 
FROM Item1DATA i1 
LEFT JOIN Item2Data i2 
ON i1.SoteID = i2.StoreID 

Aquí está una consulta dinámica que hice. Obtenido las columnas son datos generados:

--Get string of aggregate columns for pivot. The aggregate columns are the last 5 NRS Years. 
        DECLARE @aggcols NVARCHAR(MAX) 

        SELECT @aggcols = STUFF((SELECT '],[' 
                 + CAST(ny2.NRS_YEAR AS CHAR(4)) 
               FROM  mps.NRS_YEARS ny2 
               WHERE ny2.NRS_YEAR BETWEEN @NRS_Year 
                 - 5 AND @NRS_Year 
               ORDER BY '],[' 
                 + CAST(ny2.NRS_YEAR AS CHAR(4)) 
              FOR 
               XML PATH('')) , 1 , 2 , '') 
          + ']' ; 

--While we're at it, get a sum of each year column. we'll do a union query instead of rollup because that's how we roll. 

        DECLARE @sumcols NVARCHAR(MAX) ; 
        SELECT @sumcols = STUFF((SELECT ']),sum([' 
                 + CAST(ny2.NRS_YEAR AS CHAR(4)) 
               FROM  mps.NRS_YEARS ny2 
               WHERE ny2.NRS_YEAR BETWEEN @NRS_Year 
                 - 5 AND @NRS_Year 
               ORDER BY ']),sum([' 
                 + CAST(ny2.NRS_YEAR AS CHAR(4)) 
              FOR 
               XML PATH('')) , 1 , 3 , '') 
          + '])' ; 

        DECLARE @Query NVARCHAR(MAX) ; 
--Construct dynamic pivot query 

        SET @Query = N'SELECT MonthName as Month, ' + @aggcols 
         + N' 
     into ##MonthHourPivot 
FROM 
(SELECT nc.MONTHNAME, nc.MonthOfNRS_Yr, nc.NRS_YEAR, st.Hours 
FROM mps.NRS_Calendar nc 
INNER JOIN dbo.StudentTime st 
ON nc.Date = /*00:00:00 AM*/ DATEADD(dd, DATEDIFF(dd, 0, /*On*/ st.EntryDateTime), 0) 
LEFT JOIN mps.vw_ScheduleRoomBuilding srb 
ON st.ScheduleID = srb.ScheduleID 
WHERE (st.EntryDateTime <= GETDATE() and st.SiteCode = ''' + @SiteCode 
         + N''' or ''' + @SiteCode + N''' = ''All'') 
AND (srb.Abbreviation = ''' + @Building + N''' or ''' + @Building 
         + N''' = ''All'')) p 
PIVOT 
(
sum(p.Hours) 
FOR NRS_Year IN 
(' + @aggcols + N') 
) AS pvt 
' ; 

--Execute It. 
        EXECUTE(@Query) ; 

        SET @Query = N'Select [Month], ' + @aggcols 
         + N'FROM ##MonthHourPivot UNION ALL SELECT ''Total'' as [Month], ' 
         + @sumcols + ' FROM ##MonthHourPivot' ; 
        Execute (@Query); 
+0

Creo que tienes razón, Nate. Nuestro DBA acaba de señalar (como hace cinco minutos) que estoy tratando de juntar dos tipos diferentes de columnas. Ella no tenía la respuesta en este momento sobre cómo pivotar en los diversos elementos utilizando una combinación de fechas. ¿Alguna idea? – DataGirl

+0

Acabo de actualizar. – NateMpls

+1

Otra pregunta, ¿necesita que los elementos se generen dinámicamente? – NateMpls

0

Esto parece algo más apropiado con una herramienta ETL.

No conozco muy bien el conjunto de herramientas de Microsoft, pero supongo que su paquete de almacenamiento de datos tiene algo para hacer eso. En "Integración de datos" (caldera) de Pentaho, usaría un row denormalizer step, o el row flattener step.

+0

Gracias por la respuesta. Desafortunadamente, no puedo usar un ETL. El procedimiento almacenado que construiré usando esta tabla dinámica se insertará en un producto existente. – DataGirl