我有下表和记录:
示例:
表名:测试
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,'+@Stff+'
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 ('+@stuff+')
group by cola
having(select count(DISTINCT colc)
from tft b where b.cola= a.cola and colc in('+@stuff+'))= 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 ('+@stuff+')
) AS pvt';
print(@sql);
exec(@sql);
。
注意:以下脚本可以正常使用预期的结果但问题在于查询性能,因为我连接了多次数百万的同一个表记录导致我等待很长时间。
数据透视表脚本:
{{1}}
问题:问题在于长时间延迟的巨大记录。有没有更好的方法来编写相同的概念?
答案 0 :(得分:1)
这是另一种方式,它避免使用DISTINCT
并使用和而不是枢轴功能:
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
我已对其进行了测试,并使用您的示例数据返回与查询相同的结果。