Received: from localhost (unknown [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id 321A62E0104 for ; Fri, 22 Feb 2008 14:07:13 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-maia, port 10024) with ESMTP id 18024-05 for ; Fri, 22 Feb 2008 14:07:06 -0400 (AST) X-Greylist: delayed 00:06:39.782023 by SQLgrey-1.7.5 Received: from crowfix.com (crowfix.com [216.240.38.154]) by postgresql.org (Postfix) with ESMTP id 5C3502E00DD for ; Fri, 22 Feb 2008 14:07:05 -0400 (AST) Received: (qmail 8650 invoked by uid 1000); 22 Feb 2008 18:00:21 -0000 Date: Fri, 22 Feb 2008 10:00:21 -0800 From: felix@crowfix.com To: pgsql-sql@postgresql.org Subject: Delete with foreign keys Message-ID: <20080222180021.GA7700@crowfix.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.16 (2007-06-09) X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.485 tagged_above=0 required=5 tests=AWL=0.485 X-Spam-Level: X-Archive-Number: 200802/164 X-Sequence-Number: 30255 I have three tables -- CREATE TABLE name (id INT PRIMARY KEY, str VARCHAR(20)); CREATE TABLE place (id INT PRIMARY KEY, name_id INT REFERENCES name(id)); CREATE TABLE data (id INT PRIMARY KEY, place_id INT REFERENCES place(id)); I want to delete all place and data rows which reference specific names, but not the names themselves. I can do it like this: DELETE FROM data d WHERE exists (SELECT id from place p WHERE d.place_id = p.id AND p.name_id IN (SELECT id FROM name WHERE str LIKE 'Fredonia%')); DELETE FROM place WHERE name_id IN (SELECT id FROM name WHERE str LIKE 'Fredonia%'); but it seems rather roundabout, and I wonder whether the EXISTS and IN business is slow. Is there some way to do it using JOINs? I think of something like this: DELETE FROM place p, name n WHERE p.name_id = n.id AND n.str LIKE 'Fredonia%'; but I don't want to delete the name rows. Then I think of this: DELETE FROM place p WHERE p.name_id = name.id AND name.str LIKE 'Fredonia%'; but I feel uneasy about the two separate name references when the table is not named in the FROM clause. Maybe that's just my novicity. I also wonder about getting fancy and ending up with SQL specific to a database; I don't have any plans to migrate, but I try to avoid branding my SQL. -- ... _._. ._ ._. . _._. ._. ___ .__ ._. . .__. ._ .. ._. Felix Finch: scarecrow repairman & rocket surgeon / felix@crowfix.com GPG = E987 4493 C860 246C 3B1E 6477 7838 76E9 182E 8151 ITAR license #4933 I've found a solution to Fermat's Last Theorem but I see I've run out of room o