How about this?
; WITH CTE AS
(
SELECT P.CustomerID
, Indicator1 = CASE WHEN P.ProductCode IN('A') THEN 0
WHEN P.ProductCode IN('C') THEN -1
END
, Indicator2 = CASE WHEN P.ProductCode IN('B') THEN 1
ELSE 0
END
FROM #Purchase P
WHERE P.ProductCode IN ('A','B','C')
)
SELECT C.CustomerID
FROM CTE C
GROUP BY C.CustomerID
HAVING SUM (C.Indicator1) = 0 AND SUM(C.Indicator2) > 0
On a million row table, i get this:
SQL Server Execution Times:
CPU time = 93 ms, elapsed time = 294 ms.
On ten million row, i get this:
SQL Server Execution Times:
CPU time = 888 ms, elapsed time = 526 ms.
{Edit 1 : added ten million statistics}
{Edit 2 - Removing P.ProductCode, which by the way is not required,from CTE cuts down extra scan}
{Edit 3: Fixed the bug noted by Toby Harman}
{message deleted}
Hate to point this out, but ColdCoffee's approach is returning inaccurate results.
Specifically, it returns customers 6 and 7 from the original test data.
Toby Harman (3/29/2012)
Hate to point this out, but ColdCoffee's approach is returning inaccurate results.Specifically, it returns customers 6 and 7 from the original test data.
That proves why my code was fast Thanks Toby.
Edited the code; which runs a touch slower than Jeff's
mark hutchinson (3/28/2012)
@JeffDid you compare the speed of this query against one where your first (Group By) From clause is a Select Distinct (sub) query?
Nice article. It builds nicely for the reader.
I love seeing the Except clause being introduced to the reader who, like me, cut our teeth on SQL92 and need to learn newer language features to be more productive.
Thanks for the feedback, Mark.
To answer your question, I guess I'd need to see the code example you're talking about because I'm not sure that a SELECT DISTINCT would actually work here.
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 15 posts - 31 through 45 (of 166 total)
You must be logged in to reply to this topic. Login to reply