2014-11-24 88 views
0

我有以下表中的记录:的SQL Server 2008 R2:动态数据透视表的查询性能

表名:测试

cola colb colc 
------------------- 
111 222 A1 
111 333 A2 
111 344 A3 
111 444 A4 
5443 555 B1 
767 222 A1 
767 333 A2 
767 344 A3 
8998 222 A1 
8998 333 A2 

我想要处理这个数据:我想显示一些具体的colc数据透视表是属于cola只有值不是别人。例如在下面的脚本中显示A1,A2,A3属于767恰恰不会多或少。

注意:下面的脚本正常工作与预期的结果的问题是与查询性能,因为我参加很多次同样的表,该表的数百万条记录这使我等待很长一段时间循环。

透视表脚本

Declare @sql varchar(max) 
Declare @stuff varchar(max) = 'A1,A2,A3' 

SET @sql = 'SELECT cola,Available,'[email protected]+' 
      FROM      
      (
       SELECT v.cola,v.colc,c.Available 
       FROM tft AS v 
       inner join 
       (
        select cola,count(distinct colc) AS Available 
        FROM tft a 
        where colc in ('[email protected]+') 
        group by cola 
        having(select count(DISTINCT colc) 
        from tft b where b.cola= a.cola and colc in('[email protected]+'))= 3 
        and (select count(DISTINCT colc) from tft c where c.cola = a.cola) = 3 
       ) c 
       on c.cola = v.cola 
      ) p      
      PIVOT     
      (   
       count(colc)       
       FOR colc IN ('[email protected]+')       
      ) AS pvt'; 

print(@sql); 
exec(@sql); 

问题:问题是巨大的纪录这使得很长一段时间的延迟。有没有更好的方法来编写相同的概念?

+1

开始杀死这些区别。这些可能会花费你的时间。然后继续并发布查询计划。 – TomTom 2014-11-24 12:34:49

+0

@TomTom,如果我这样做,那么我无法得到结果。 :( – MAK 2014-11-24 12:49:05

+0

@TomTom,因为我想在having子句中计算不同的'colc'。 – MAK 2014-11-24 12:49:54

回答

1

这里有一个替代方法,它避免了DISTINCT S和使用总和,而不是旋转功能:

SELECT orig.cola , 
     colas.counter , 
     SUM(CASE orig.colc WHEN 'A1' THEN 1 ELSE 0 END) AS A1 , 
     SUM(CASE orig.colc WHEN 'A2' THEN 1 ELSE 0 END) AS A2 , 
     SUM(CASE orig.colc WHEN 'A3' THEN 1 ELSE 0 END) AS A3 
FROM tft orig 
     INNER JOIN (SELECT cola , 
          COUNT(1) AS counter 
        FROM (SELECT cola , 
             colc 
           FROM  tft 
           WHERE  cola NOT IN (
             SELECT cola 
             FROM tft 
             WHERE colc NOT IN ('A1', 'A2', 'A3')) 
           GROUP BY cola , 
             colc 
          ) a 
        GROUP BY cola 
        HAVING COUNT(1) > 2 
        ) colas ON colas.cola = orig.cola 
GROUP BY orig.cola , 
     colas.counter 

我已经测试过它,它返回的查询使用示例数据相同的结果。