Reputation: 7260
I have the following table with the records:
Example:
Table Name: Test
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
What I want to do with this data: I want to show the pivot table with some specific colc
values which are belongs to cola
values only not others. For example in the below script shown that A1,A2,A3
belongs to 767
exactly not more or less then that.
Note: The below script works fine with the expected result BUT the problem is with the query performance because I am joining many times the same table which is of millions of records which cause me waiting for long while loop.
Pivot table script:
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);
Problem: The problem is with the huge records which makes a delay for long while. Is there any better way to write same concept?
Upvotes: 0
Views: 380
Reputation: 6771
Here's an alternate way, it avoids the DISTINCT
s and uses a sum instead of the pivot function:
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
I have tested it and it returns the same results as your query using your sample data.
Upvotes: 1