Received: from megazone.bigpanda.com (megazone.bigpanda.com [63.150.15.178]) by postgresql.org (Postfix) with ESMTP id 1F3C1474E49 for ; Wed, 31 Jul 2002 16:08:43 -0400 (EDT) Received: by megazone.bigpanda.com (Postfix, from userid 1001) id CD872D609; Wed, 31 Jul 2002 13:08:43 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by megazone.bigpanda.com (Postfix) with ESMTP id C33CE5C04; Wed, 31 Jul 2002 13:08:43 -0700 (PDT) Date: Wed, 31 Jul 2002 13:08:43 -0700 (PDT) From: Stephan Szabo To: Jinn Koriech Cc: PostgreSQL Mailing List Subject: Re: negative queries puzzle In-Reply-To: <1028142936.16285.44.camel@morph.magiclamp.2y.net> Message-ID: <20020731130557.A19958-100000@megazone23.bigpanda.com> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Archive-Number: 200207/461 X-Sequence-Number: 8839 On 31 Jul 2002, Jinn Koriech wrote: > hi all, > > here's a query i've never been able to improve: > > i have an old data set and a new data set - in this case uk postcodes > with eastings and northings. i want to extract the new and changed > postcodes from the new set. to get the changed entries i use a join and > it works okay: > > SELECT n.postcode, n.easting, n.northing FROM v_postcode_new n, > v_postcode_old o WHERE n.postcode = o.postcode AND (n.easting <> > o.lattitude OR n.northing <> o.longitude); > > > but then to get the entirely new items out i use a sub query which takes > for ever > > SELECT DISTINCT * FROM v_postcode_new WHERE postcode NOT IN ( SELECT > postcode FROM v_postcode_old ) ORDER BY postcode ASC; > > does anyone know of a quicker way to accomplish this? i guess there > must be some cleaver way around it, but it's beyond me. Hmm, a couple of possible other queries: -- Do you really need the distinct? select distinct * from v_postcode_new where not exists ( select * from v_postcode_old where v_postcode_old.postcode= v_postcode_new.postcode); Or maybe (just thought of this, think it should work, but am not entirely sure) select distinct v_postcode_new.* from v_postcode_new left outer join v_postcode_old using(postcode) where v_postcode_old.postcode is null;