X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by postgresql.org (Postfix) with ESMTP id C7E329DCBC7 for ; Wed, 8 Feb 2006 13:56:32 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 02169-05 for ; Wed, 8 Feb 2006 13:56:32 -0400 (AST) X-Greylist: delayed 00:24:00.943594 by SQLgrey- Received: from nelson.osl.com (216-21-133-120.ip.van.radiant.net [216.21.133.120]) by postgresql.org (Postfix) with ESMTP id 726BB9DCBC3 for ; Wed, 8 Feb 2006 13:56:29 -0400 (AST) Content-class: urn:content-classes:message MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-MimeOLE: Produced By Microsoft Exchange V6.5.7226.0 Subject: Re: Delete with join -- deleting related table entries? Date: Wed, 8 Feb 2006 09:56:28 -0800 Message-ID: <144D12D7DD4EC04F99241498BB4EEDCC20CC6E@nelson.osl.com> X-MS-Has-Attach: X-MS-TNEF-Correlator: Thread-Topic: [SQL] Delete with join -- deleting related table entries? Thread-Index: AcYs1v7zEVPPTa00SJuW6NZQPDXtdAAAFnJg From: "Owen Jacobson" To: X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, score=0.103 required=5 tests=[AWL=0.103, UPPERCASE_25_50=0] X-Spam-Score: 0.103 X-Spam-Level: X-Archive-Number: 200602/80 X-Sequence-Number: 24090 Bryce Nesbitt wrote:=20 > Owen Jacobson wrote: > > > BEGIN; > > DELETE FROM note WHERE issue_id IN (SELECT issue_id FROM isuse > > WHERE reservation_id =3D reservation_to_delete); > > DELETE FROM isuse WHERE reservation_id =3D reservation_to_delete; > > DELETE FROM reservations WHERE reservation_id =3D=20 > reservation_to_delete; > > COMMIT; > > > > With an appropriate value or expression substituted into=20 > > reservation_to_delete. This would be the "hard way", but (as=20 > > it's in a single transaction) will still protect other=20 > > clients from seeing a partial delete. > > Yup, that's exactly how I delete reservations one a time. But here I > need to select a few thousand reservations, and I don't think=20 > this will > work: > BEGIN; > DELETE FROM note WHERE issue_id IN (SELECT issue_id FROM isuse > WHERE reservation_id IN > (select reservation_id from reservations where date > magic); > DELETE FROM isuse WHERE reservation_id IN > (select reservation_id from reservations where date > magic) > DELETE FROM reservations WHERE reservation_id IN > (select reservation_id from reservations where date > magic) > COMMIT; >=20 > I suppose I can do the subselect as a perl wrapper, but I was thinking > that maybe SQL could do it all for me.... Further thinking produced the following functional example. CREATE TABLE reservation ( reservation_id INTEGER NOT NULL, date DATE NOT NULL ); CREATE TABLE issue ( issue_id INTEGER NOT NULL, reservation_id INTEGER NOT NULL ); CREATE TABLE note ( issue_id INTEGER NOT NULL ); INSERT INTO reservation VALUES (1, '2006-01-01'); INSERT INTO reservation VALUES (2, '2006-01-15'); INSERT INTO reservation VALUES (3, '2006-02-01'); INSERT INTO issue VALUES (1, 1); INSERT INTO issue VALUES (2, 1); INSERT INTO issue VALUES (3, 2); INSERT INTO issue VALUES (4, 2); INSERT INTO issue VALUES (5, 3); INSERT INTO issue VALUES (6, 3); INSERT INTO note VALUES (1); INSERT INTO note VALUES (2); INSERT INTO note VALUES (3); INSERT INTO note VALUES (4); INSERT INTO note VALUES (5); INSERT INTO note VALUES (6); -- PostgreSQL 8.0 and prior BEGIN; DELETE FROM note WHERE note.issue_id =3D issue.issue_id AND issue.reservation_id =3D reservation.reservation_id AND reservation.date > '2006-01-16'; DELETE FROM issue WHERE issue.reservation_id =3D reservation.reservation_id AND reservation.date > '2006-01-16'; DELETE FROM reservation WHERE date > '2006-01-16'; COMMIT; -- PostgreSQL 8.1 and later BEGIN; DELETE FROM note USING issue, reservation WHERE note.issue_id =3D issue.issue_id AND issue.reservation_id =3D reservation.reservation_id AND reservation.date > '2006-01-16'; DELETE FROM issue USING reservation WHERE issue.reservation_id =3D reservation.reservation_id AND reservation.date > '2006-01-16'; DELETE FROM reservation WHERE date > '2006-01-16'; COMMIT; The version using subselects works fine, too. -Owen