2011-05-04 23 views
6

我还没有看到过这样的问题,但如果有问题已经得到解答,请告诉我。我不得不使用存储过程创建导出。不幸的是,目前在SSRS中创建此报告是不可能的。加入多个动态数据透视表

我需要做的是动态创建一个数据透视表并将其与另一个数据库联合 - 或者这就是我认为的工作原理。

的原始数据的工作原理类似于这个(我已经改变了的项目,以保护我公司的数据):

Data Sample

他们想要的数据,看起来像在报告中是这样的(为了节省空间,我没有使用所有日期,但你可以得到这个想法): Report Sample

我创建了一个临时表并创建了两个动态数据透视表。两个表都将单独工作,但是一旦我使用UNION ALL,我会收到一条错误消息(我将在下面添加)。我包含了我用来创建两个枢纽的代码。有人能告诉我我做错了什么吗?

是否有可能在一个关键点上做到这一点?

/* 
    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) 

该错误消息我收到如下:

警告:Null值由聚合或其它SET操作消除。 Msg 8114,级别16,状态5,行1 将数据类型varchar转换为bigint时出错。

回答

6

我的想法是列不匹配(列数,列顺序和数据类型)。如果我正确读取您的查询,如果item1和item2的问题日期不匹配,那么您可能会得到不匹配的列。没有看到这两个查询的输出结果就很难说。

您确定不想根据商店ID加入吗?

喜欢的东西:

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 

下面是一个动态查询我做到了。得到的列是数据生成的:

--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

我认为你是对的,Nate。我们的DBA刚刚指出(如在五分钟前)我试图将两种不同的列类型放在一起。她目前还没有答复如何使用日期组合来转换各种项目。有什么想法吗? – DataGirl 2011-05-04 15:25:52

+0

我刚刚更新。 – NateMpls 2011-05-04 15:28:50

+1

另一个问题,你需要动态生成的项目? – NateMpls 2011-05-04 15:30:55

0

这似乎是更适合使用ETL工具的东西。

我不太了解Microsoft的工具集,但我认为他们的数据仓库软件包有这样做的功能。在Pentaho的“数据集成”(Kettle)中,您可以使用row denormalizer steprow flattener step

+0

感谢您的回答。不幸的是,我无法使用ETL。我将使用此数据透视表构建的存储过程将被拉入现有产品中。 – DataGirl 2011-05-04 15:22:38