tags:

views:

162

answers:

5

OK, I need a T-SQL guru for this one.

I have a table called PackageStoreEvents that has a packageid, storecode and an eventcode field. I want to return the packageid values for storecode 2406 where the count for the eventcode = 6 is 0.

How would I do that?

I'm stuck on this one.

Thanks for the help

+6  A: 

This is not wildly pretty, but should work. You left join to the same table including the eventcode in the join condition, assert that the right table has no rows with IS NULL, and then do a DISTINCT to avoid the many rows that would otherwise be returned.

SELECT  DISTINCT p1.packageid
FROM    PackageStoreEvents p1
        LEFT JOIN
                PackageStoreEvents p2
                ON p1.packageid = p2.packageid
                AND p1.storecode = p2.storecode
                AND p2.eventcode = 6
WHERE p2.packageid IS NULL
AND   p1.storecode = 2406
David M
This will work, but it's definitely not the best method.
Kenneth
+ 1 for being a bass trombonist
Ben McCormack
@Kenneth - so post a better one. It's the only one so far that will actually work.
David M
@Ben - Thanks :)
David M
Would whoever has given this -1 please justify themselves or remove it? Common courtesy guys...
David M
You forgot to include storecode in the join and where clauses but the general idea is correct. Oh, and I didn't give it a -1, I gave it a +1, so that wasn't me. :)
Charles Boyung
@Charles - thanks, I missed that bit - now included.
David M
This one seems to work. Thanks all for the responses!
A: 

Maybe this?:

SELECT PackageID
FROM PackageStoreEvents
WHERE Storecode = 2406 and EventCode = 6
GROUP BY PackageID 
HAVING COUNT(EventCode) = 0
Leslie
You beat me to it. Only difference is the unnecessary columns you're returning. Either way, you have my vote.
Kenneth
This will not work. Your WHERE clause is going to force this query to only get rows where EventCode equals 6. Then your HAVING will filter out all of those rows.
Charles Boyung
This won't work. The WHERE and the HAVING between them will ensure no rows are returned.
David M
I see what you're saying...
Leslie
Doh, how did I not see that...
Kenneth
+1  A: 
SELECT packageid
FROM 
PackageStoreEvents p1
WHERE storecode = 2406
AND NOT EXISTS (SELECT * FROM PackageStoreEvents p2
                 WHERE p1.packageid = p2.packageid
                AND p1.storecode = p2.storecode
                AND p2.eventcode = 6)
Martin Smith
+2  A: 

Assuming I understand the question correctly I would use something along the lines of this :

-- PackageStoreEvents (packageid, storecode, eventcode)

SELECT DISTINCT packageid
  FROM PackageStoreEvents r
 WHERE storecode = 2406
   AND NOT EXISTS ( SELECT *
                      FROM PackageStoreEvents cnt
                     WHERE cnt.packageid = r.packageid
                       AND cnt.storecode = r.storecode
                       AND cnt.eventcode = 6)
deroby
LOL, I type to slow it seems, Martin beat me by a minute =)(yet, it's reassuring two people came up with the same solution.. at least I'm not the only one who looks silly when it turns out to be wrong =P)
deroby
Sjeezzz, I needed 3 edits to get it right ... (and hadn't seen the double NOT until you pointed it out... thank-god it's Friday!)(And I only dare _assume_ it's right now...)
deroby
+6  A: 

Try:

select packageid 
from PackageStoreEvents
where storecode = 2406
group by packageid
having sum(case eventcode when 6 then 1 else 0 end)=0;

for a single-pass query.

Mark Bannister
+1 I like that solution. (By the way I fixed up the code formatting on it)
Martin Smith
Looks like the most efficient option to me.
Mark Storey-Smith
Thanks, Martin.
Mark Bannister