Had a play with this and was very impressed - nice job.
I played around and added this index
CREATE INDEX IX_#Purchase_ProductCode
ON #Purchase (
ProductCode)
INCLUDE (CustomerID)
One concern I had was looking at the query plan, the EXCEPT does a clustered index scan. That may be a function of the small data set, but I am not sure.
My preference for these types of queries has always been to do an OUTER JOIN on the one we don't want selected and then say that we only want the ones that didn't match returned.
SELECT a.CustomerID
FROM #Purchase a
LEFT OUTER JOIN #Purchase b
ON b.CustomerID = a.CustomerID
AND b.ProductCode IN ('C')
WHERE a.ProductCode IN ('A','B')
AND b.CustomerID IS NULL
GROUP BY a.CustomerID
HAVING COUNT(DISTINCT a.ProductCode) = 2
Any thoughts?