Received: from localhost (unknown [200.46.204.183]) by developer.postgresql.org (Postfix) with ESMTP id DB3CB2E003E for ; Thu, 3 Apr 2008 05:53:47 -0300 (ADT) Received: from developer.postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 44770-10 for ; Thu, 3 Apr 2008 05:53:40 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from vsmtp21.tin.it (vsmtp21.tin.it [212.216.176.109]) by developer.postgresql.org (Postfix) with ESMTP id A8BF52E002D for ; Thu, 3 Apr 2008 05:53:40 -0300 (ADT) Received: from kerberos.webthatworks.it (82.48.130.181) by vsmtp21.tin.it (7.3.122) id 47AB330F02E4D0AA for pgsql-sql@postgresql.org; Thu, 3 Apr 2008 10:53:38 +0200 Received: from stige.webthatworks.it (odark.webthatworks.it [192.168.1.72]) by kerberos.webthatworks.it (Postfix) with ESMTP id B37F3E6A96 for ; Thu, 3 Apr 2008 10:53:37 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by stige.webthatworks.it (Postfix) with ESMTP id 39DF8578FC for ; Thu, 3 Apr 2008 10:53:37 +0200 (CEST) Date: Thu, 3 Apr 2008 10:53:36 +0200 From: Ivan Sergio Borgonovo To: pgsql-sql@postgresql.org Subject: Re: update with join Message-ID: <20080403105336.2ca72046@webthatworks.it> In-Reply-To: <690707f60804021954x6d4f19aas22de2def30f5c1de@mail.gmail.com> References: <20080402224753.78f454fc@webthatworks.it> <690707f60804021954x6d4f19aas22de2def30f5c1de@mail.gmail.com> Organization: www.WebThatWorks.it X-Mailer: Claws Mail 3.3.1 (GTK+ 2.12.9; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200804/17 X-Sequence-Number: 30556 On Wed, 2 Apr 2008 23:54:18 -0300 "Osvaldo Kussama" wrote: > 2008/4/2, Ivan Sergio Borgonovo : > > I've > > > > create table types( > > typeid int, > > special boolean not null > > ); > > > > create table methods( > > methodid int, > > typeid references types(typeid), > > ); > > > > create table orders( > > orderid int > > ); > > > > create table order_payments( > > payid int > > orderid references order(orderid), > > methodid references method(methodid), > > issued boolean not null default false > > ); > > > > orderid payid methodid special > > 1 1 1 t > > 1 2 2 t > > 1 3 3 t > > 1 4 4 f > > 1 5 4 f > > > > I'd like to chose one payid > > If the payid is "special" just set issued to true for that payid, > > leave the other unchanged. > > If the payid is not "special" set issued for all the payid in the > > same order. > > > > eg. > > So if payid=4 I'd have > > > > orderid payid methodid special issued > > 1 1 1 t t > > 1 2 2 t t > > 1 3 3 t t > > 1 4 4 f t > > 1 5 4 f t > > > > and if payid=2 > > > > orderid payid methodid special issued > > 1 1 1 t f > > 1 2 2 t t > > 1 3 3 t f > > 1 4 4 f f > > 1 5 4 f f > > > > This stuff below doesn't work: > > > > update order_payments > > set issued=true where payid in ( > > select p.payid > > from order_payments p > > join methods as m on m.methodid=p.methodid > > join types as t on m.typeid=t.typeid > > where (p.orderid=%d and not t.special) or p.payid=%d); > > > > and I can understand why but I can't rewrite it to make it work. > > > > Try: > UPDATE order_payments > SET issued=true FROM methods m, types t > WHERE m.methodid=p.methodid AND p -> order_payments > m.typeid=t.typeid AND > ((order_payments.orderid=%d AND NOT t.special) OR > order_payments.payid=%d)); one less ) Even after correcting the few typos this version obtain the same result of update order_payments set issued=true where payid=%d I ended up in writing a plpgsql function that retrieve special and then have an if block. create or replace function IssuePay(_PayID int, out _OrderGroupID bigint, out _Online boolean) as $$ begin select into _OrderGroupID, _OnLine p.OrderGroupID, t.OnLine from shop_commerce_ordergroup_pay p join shop_commerce_paymethods m on p.PayMethodID=m.MethodID join shop_commerce_paytypes t on m.TypeID=t.TypeID where PayID=_PayID; if(_OnLine) then update shop_commerce_ordergroup_pay set Issued=true where PayID=_PayID; else update shop_commerce_ordergroup_pay set Issued=true where OrderGroupID=_OrderGroupID; end if; return; end; $$ language plpgsql; mutatis mutandis. It may not be the most elegant thing but it is enough encapsulated it won't be a pain to refactor once I become a better DBA or someone else point out a better solution on the list. I'd be curious if it had a performance penalty over a one update statement. thanks -- Ivan Sergio Borgonovo http://www.webthatworks.it