Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id A29904764D9 for ; Tue, 3 Dec 2002 15:11:32 -0500 (EST) Received: from beamish.nsd.ca (unknown [205.150.156.194]) by postgresql.org (Postfix) with ESMTP id 8F56F476DD4 for ; Tue, 3 Dec 2002 14:53:08 -0500 (EST) Received: (from smap@localhost) by beamish.nsd.ca (8.9.3/8.9.3) id OAA12871; Tue, 3 Dec 2002 14:53:07 -0500 X-Authentication-Warning: beamish.nsd.ca: smap set sender to using -f Received: from reddog.nsd.ca(192.168.101.30) by beamish.nsd.ca via smap (V2.1/2.1+anti-relay+anti-spam) id xma012869; Tue, 3 Dec 02 14:52:51 -0500 Received: from nsd.ca (jllachan-linux.nsd.ca [192.168.101.148]) by reddog.nsd.ca (8.8.7/8.8.7) with ESMTP id OAA24891; Tue, 3 Dec 2002 14:51:32 -0500 Message-ID: <3DED0BA2.17DF0B8C@nsd.ca> Date: Tue, 03 Dec 2002 14:53:06 -0500 From: Jean-Luc Lachance X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.4.9-31 i686) X-Accept-Language: en MIME-Version: 1.0 To: eric soroos Cc: pgsql-sql@postgresql.org Subject: Re: Query for filtering records References: <57018518.1173209203@[4.42.179.151]> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200212/44 X-Sequence-Number: 10632 Eric try: select num, p1,p2 ... from contacts inner join groups using (contacts.num=groups.contactNum) where groups.groupNum=a and contact.p3=b and not exists ( select 1 from groups g2 where g2.contactNum = groups.contactNum and g2.groupNum != a); or select num, p1,p2 ... from contacts inner join groups using (contacts.num=groups.contactNum) where groups.groupNum=a and contact.p3=b and groups.groupNum in ( select contactNum from groups group by contactNum having count(*) = 1); The IN version may still be faster as the sub-select should be evaluated only once; JLL eric soroos wrote: > > I'm having trouble subtracting groups from other groups. > > I've got a data model that has the following essential features: > > create table contacts (num int, properties....); > create table groups (groupNum int, contactNum int); > > Where not all contacts will be in a group, some groups will contain most contacts, and there will be something like hundreds of groups and tens of thousands of contacts. I allow people to build groups using criteria, which I need to programatically translate to sql. > > One somewhat common pattern is: > > Select all contacts in group a, who have property b, and who aren't in groups c,d,e,f... > > My first shot was subqueries: > > select num, p1,p2 ... from contacts > inner join groups using (contacts.num=groups.contactNum) > where groups.groupNum=a > and contact.p3=b > and not num in (select contactNum from groups where groupNum=c) > and not num in (select contactNum from groups where groupNum=d) > and not num in (select contactNum from groups where groupNum=e) > and not num in (select contactNum from groups where groupNum=f) > > This is .... slow. agonizingly so. > > With an inner join, I'm not convinced that the subtraction is actually correct., but it is much faster. Unfortunatley, faster incorrect answers are rarely helpful. > > Outer joins seem even worse than subselects for speed, but it does appear to give the correct answer. (example with a single join.) > > select num from contacts > left outer join groups > on (contacts.num=groups.contactNum > and groups.groupNum=b) > where > dl_groupDonor._groupNum is null > and p3=c > > I've got to be missing something here, because this is much slower from the (slow) procedural system that I'm porting from. > > I've been avoiding using union / intersect since I don't really ever know what columns are going to be in the query. perhaps I should revisit that decision and try to work around it. > > eric > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)