如何创建Sql Server 2008交叉表动态查询?

时间:2012-01-31 19:17:46

标签: sql sql-server-2008

我有3张桌子:

  • 地点LocationID, LocationName
  • 缺陷DefectID, DefectType
  • 反馈feedbackID, DefectID, LocationID

我需要以下格式的交叉表报告:位置列下面的数字是该位置的缺陷总数。地点可以是任何数字。它应该是动态的..

DefectID  DefectType  NewYork  NewJersey  Texas  Houston
1         Defect1       0         10        3       6
2         Defect2       0          0        9      10
3         Defect3       8          8        4       6

我有一个硬编码的SQL查询。此外,它没有显示DefectID ..

select 
   DefectType, 
   [1] as NewYork, 
   [4] as NewJersy,  
   [5] as Texas, 
   [6] as Houston
from (select 
             Defect.DefectID, 
             Defect.DefectType, 
             Location.LocationID  
      from Feedback
      inner join Locations on (Feedback.LocationID= Location.LocationID)             
      inner join DefectType on (Feedback.DefectID= Defect.DefectID)         
     ) p
    pivot   
     ( count (DefectID) for LocationID in ( [1], [4], [5],[6] )   ) as pvt
 order by pvt.DefectType; 

1 个答案:

答案 0 :(得分:2)

您无法使用SQL Server PIVOT和纯静态SQL动态构建交叉表值。您必须动态构建SQL,使用一些外部脚本语言构建查询,或使用T-SQL使用execute

DECLARE @locationID int, @LocationName nvarchar(50), 
  @columnList nvarchar(max), @idList nvarchar(max), @sql nvarchar(max) ;
DECLARE location_cursor CURSOR
    FOR SELECT locationID, LocationName FROM Locations

SET @columnList = '';
SET @idList = '';


OPEN location_cursor
FETCH NEXT FROM vendor_cursor 
INTO @locationID, @LocationName;
WHILE @@FETCH_STATUS = 0
BEGIN
  SET @columnList = @columnList + ', [' + @locationID + '] as [' + @locationName + ']'
  SET @idList = @idList + '[' + @locationID + '],'
END
CLOSE location_cursor

SET @sql = 'select DefectType' + @columnList + ' from (select Defect.DefectID, Defect.DefectType, Location.LocationID from Feedback inner join Locations on (Feedback.LocationID= Location.LocationID)
inner join DefectType on (Feedback.DefectID= Defect.DefectID)
) p pivot
( count (DefectID) for LocationID in (' + left(@idList,len(@idList)-1) + ') ) as pvt order by pvt.DefectType'

EXECUTE (@sql)

显然,我没有对此进行测试,但它应该可行(可能需要进行小的调整)。