Received: from localhost (unknown [200.46.204.182]) by postgresql.org (Postfix) with ESMTP id AAF2E9FA4DB for ; Fri, 26 Oct 2007 04:53:57 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.182]) (amavisd-maia, port 10024) with ESMTP id 93009-06 for ; Fri, 26 Oct 2007 04:53:38 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from smtp27.orange.fr (smtp27.orange.fr [80.12.242.95]) by postgresql.org (Postfix) with ESMTP id CD5559FA40D for ; Fri, 26 Oct 2007 04:53:51 -0300 (ADT) Received: from me-wanadoo.net (localhost [127.0.0.1]) by mwinf2714.orange.fr (SMTP Server) with ESMTP id 400111C000AA for ; Fri, 26 Oct 2007 09:53:48 +0200 (CEST) Received: from scoobydo (ARennes-352-1-33-17.w81-250.abo.wanadoo.fr [81.250.152.17]) by mwinf2714.orange.fr (SMTP Server) with ESMTP id C75A81C000A1; Fri, 26 Oct 2007 09:53:47 +0200 (CEST) X-ME-UUID: 20071026075347816.C75A81C000A1@mwinf2714.orange.fr From: =?iso-8859-1?Q?S=E9bastien_Meudec?= To: "'Erik Jones'" Cc: "'Christian Kindler'" , Subject: Re: get only rows for latest version of contents Date: Fri, 26 Oct 2007 09:59:08 +0200 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Office Outlook, Build 11.0.5510 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1807 In-reply-to: <8A51028E-4A4A-4C62-BEA5-54F0300BC618@myemma.com> Thread-Index: AcgXFauNNJ3oyPm6T8CAIkwjrVnc3QAjq+Sg Message-Id: <20071026075347.C75A81C000A1@mwinf2714.orange.fr> X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.001 tagged_above=0 required=5 tests=BAYES_50=0.001 X-Spam-Level: X-Archive-Number: 200710/131 X-Sequence-Number: 29503 Hi Erik Thx for your suggestion. I've done some tests and correct the order to get what i want. In fact the order i would like to have is 3,2,1,null (null is a draft version on my api). But the order ASC gives 1,2,3,null And the order DESC gives null,3,2,1 So i use order by -(version_no) that gives me 3,2,1,null SELECT DISTINCT ON (Idnode) Idnode, version_no, c1, c2, c3 FROM business GROUP BY Idnode, version_no, c1, c2, c3 ORDER BY Idnode, -(version_no) DESC; But finally, when i have wanted to inject this way in my real big = request it gives me error: SELECT DISTINCT ON expressions must match initial ORDER BY expressions Because my api requires a different order and it seems idnode should be = in first of the order to be able to use DISTINCT ON. So for now, i'll keep Chris solution. I have not profile it with large tables but it's the only solution i = have for now ;) Thx everybody. Regards Sebastien > -----Message d'origine----- > De=A0: Erik Jones [mailto:erik@myemma.com] > Envoy=E9=A0: jeudi 25 octobre 2007 16:35 > =C0=A0: S=E9bastien Meudec > Cc=A0: 'Christian Kindler'; pgsql-sql@postgresql.org > Objet=A0: Re: [SQL] get only rows for latest version of contents >=20 >=20 > On Oct 25, 2007, at 1:50 AM, S=E9bastien Meudec wrote: >=20 > > Thx a lot Chris. > > > > In fact the correct SQL was (rewritten with inner join because of > > it is > > required by my api): > > > > select b1.* > > from business b1 > > inner join (select idnode,max(version_no) as version_no from = business > > group by idnode) as b2 > > on b1.idnode =3D b2.idnode and > > (b1.version_no =3D b2.version_no or b2.version_no is null) > > > > Regards, > > Seb. > > > > > >> -----Message d'origine----- > >> De : pgsql-sql-owner@postgresql.org [mailto:pgsql-sql- > >> owner@postgresql.org] De la part de Christian Kindler > >> Envoy=E9 : mercredi 24 octobre 2007 11:55 > >> =C0 : S=E9bastien Meudec > >> Cc : pgsql-sql@postgresql.org > >> Objet : Re: [SQL] get only rows for latest version of contents > >> > >> Hi! > >> > >> not quick mut works > >> > >> select * from business b1 > >> where b1.version_no =3D (SELECT max(version_no) FROM business b2. > >> where b2.idnode =3D b1.idnode > >> ) > >> > >> If you want to make this quiry faster du a regular join > >> > >> select b1.* > >> from business b1, > >> (SELECT max(version_no) FROM business b2. > >> where b2.idnode =3D b1.idnode > >> ) as b2 > >> where b1.idnode =3D b2.idnode > >> and b1.version_no =3D b2.version_nr > >> > >> Regards Chris > >> > >> PS written without running any sql, maybe there are some syntax > >> issues, > >> but i am shure you will figure these out :-) > >> > >> > >> > >> On Wed, October 24, 2007 11:29 am, S=E9bastien Meudec wrote: > >>> Hi everybody. > >>> > >>> I have a table like that (i simplified it): > >>> CREATE TABLE business { > >>> idnode integer not null, > >>> version_no integer, > >>> c1 text, > >>> c2 text, > >>> c3 text > >>> } > >>> With a unique index in (idnode,version_no). > >>> > >>> This table records many version from contents identified by > >>> idnode where > >>> texts may be different. > >>> So i can have: > >>> Idnode | version_no | c1 | c2 | c3 > >>> 111 | 2 | foo1 | foo2 | foo3 > >>> 111 | 1 | fee1 | foo2 | foo3 > >>> 111 | null | fee1 | fee2 | fee3 > >>> 222 | null | too1 | too2 | too3 > >>> 333 | 1 | xoo1 | xoo2 | xoo3 > >>> 333 | null | yoo1 | yoo2 | yee3 > >>> > >>> I want to select all columns but only for last (greatest) version = of > >> each > >>> content. So I want a result like: > >>> Idnode | version_no | c1 | c2 | c3 > >>> 111 | 2 | foo1 | foo2 | foo3 > >>> 222 | null | too1 | too2 | too3 > >>> 333 | 1 | xoo1 | xoo2 | xoo3 > >>> > >>> If i do: > >>> SELECT idnode, max(version_no) FROM business > >>> GROUP BY idnode ORDER BY idnode; > >>> > >>> I get effectively only last version: > >>> Idnode | version_no > >>> 111 | 2 > >>> 222 | null > >>> 333 | 1 > >>> > >>> But as soon that i want to get texts, I don't know how to build > >>> the SQL. > >>> In each SQL i tested i've been forced to put text column in a > >>> group by > >>> since > >>> i used aggregate for version_no: > >>> SELECT idnode, max(version_no), c1, c2, c3 FROM BUSINESS > >>> GROUP BY idnode, c1, c2, c3 ORDER BY idnode; > >>> > >>> But with that SQL, because of the group by and different values > >>> in text > >> i > >>> get > >>> Idnode | version_no | c1 | c2 | c3 > >>> 111 | 2 | foo1 | foo2 | foo3 > >>> 111 | 1 | fee1 | foo2 | foo3 > >>> 111 | null | fee1 | fee2 | fee3 > >>> 222 | null | too1 | too2 | too3 > >>> 333 | 1 | xoo1 | xoo2 | xoo3 > >>> 333 | null | yoo1 | yoo2 | yee3 > >>> > >>> As we can't do aggregate in join neither in where, i can't get > >>> what i > >>> want. > >>> > >>> Anybody could help me to build proper SQL ? > >>> > >>> Thx for your answers. > >>> S=E9bastien. >=20 > Here's another little trick that can come in handy for this: >=20 > SELECT DISTINCT ON (Idnode) Idnode, version_no, c1, c2, c3 > FROM business > ORDER BY Idnode, version_no DESC; >=20 > Erik Jones >=20 > Software Developer | Emma=AE > erik@myemma.com > 800.595.4401 or 615.292.5888 > 615.292.0777 (fax) >=20 > Emma helps organizations everywhere communicate & market in style. > Visit us online at http://www.myemma.com >=20