Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id E99D647624C for ; Wed, 27 Nov 2002 12:33:09 -0500 (EST) Received: from red.asis.com (red.asis.com [207.20.154.12]) by postgresql.org (Postfix) with ESMTP id D6831476689 for ; Wed, 27 Nov 2002 12:32:22 -0500 (EST) Received: from inky (06-204.139.popsite.net [64.24.222.204]) by red.asis.com (8.12.6/8.12.6) with SMTP id gARHWSGS023472 for ; Wed, 27 Nov 2002 09:32:28 -0800 (PST) (envelope-from nyoung@asis.com) From: Nathan Young To: pgsql-sql@postgresql.org Date: Wed, 27 Nov 2002 09:37:07 -0800 X-Priority: 3 (Normal) Reply-To: nathan@ncyoung.com Organization: N.C. Young Design In-Reply-To: <20021126080514.C77510-100000@megazone23.bigpanda.com> Message-Id: <98FCPJ2YA0B9EDSOVU5ZURIFVR76US2X.3de502c3@inky> Subject: Re: join question MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" X-Mailer: Opera 6.0 build 1010 X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200211/424 X-Sequence-Number: 10566 OK, that works great, but I was told that I should avoid sub-selects when possible for performance reasons. Also, I used so much mental energy trying to find a solution that would do either task using a join that I would be very curious if anyone had a solution. The setup: >> I have a table with members and a table with payments. Each payment is >> related to a member by memberID and each payment has (among other things) >> a year paid. The problem: >> I would like to be able to get a list of members who have not paid for a >> given year. Two possible solutions, both using sub-selects: > select member.memberId, member.name from member where not exists (select > * from payment where payment.memberId=member.memberID and > payment.yearPaid=2002); > > select member.memberId, member.name from member left outer join > (select * from payment where yearPaid=2002) as a using (memberId) where > yearPaid is null; In addition to my interest in finding a join that could do that, I'm curios about a couple other things. My understanding is that exists is optimized so that the first version would be faster than the second. "using (memberID)" would be the same as "on member.memberID = payment.memberID", right? Thanks! ------------->Nathan 11/26/2002 8:11:53 AM, Stephan Szabo wrote: > >On Fri, 22 Nov 2002, Nathan Young wrote: > >> Hi all. >> >> I have a table with members and a table with payments. Each payment is >> related to a member by memberID and each payment has (among other things) a >> year paid. >> >> I can create a join to find a list of members who have paid for a given year >> (2002 in this case): >> >> select member.memberID,member.name from member, payment where >> payment.memberID = member.memberID and payment.yearPaid = 2002 >> >> I would like to be able to get a list of members who have not paid for a >> given year. > >Well, I believe either of these two will do that: > > select member.memberId, member.name from member where not exists (select > * from payment where payment.memberId=member.memberID and > payment.yearPaid=2002); > > select member.memberId, member.name from member left outer join > (select * from payment where yearPaid=2002) as a using (memberId) where > yearPaid is null; > >> I would also like to combine the two criteria, for example to generate a list >> of members who have paid for 2002 but not 2003. > >I think these would do that: > >select member.memberID,member.name from member, payment where > payment.memberID = member.memberID and payment.yearPaid = 1999 > and not exists (select * from payment where > payment.memberId=member.memberId and yearPaid=2002); > >select member.memberId, member.name from member inner join (select > * from payment where yearPaid=2002) as a using (memberId) left outer join > (select * from payment where yearPaid=2003) as b using (memberId) where > b.yearPaid is null; > > > > --- (([^/]+)/([^/]+)){0,1}/*(([^/]+)/([^/]+)){0,1}/*(([^/]+)/([^/]+)){0,1}/* (([^/]+)/([^/]+)){0,1}/*(([^/]+)/([^/]+)){0,1}/*(([^/]+)/([^/]+)){0,1}/* --- Nathan Young N. C. Young Design (530)629-4176 http://ncyoung.com