X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 41D56D8396 for ; Fri, 9 Sep 2005 11:36:58 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 05809-08 for ; Fri, 9 Sep 2005 14:36:54 +0000 (GMT) Received: from sss.pgh.pa.us (sss.pgh.pa.us [66.207.139.130]) by svr1.postgresql.org (Postfix) with ESMTP id 47BEFD82E5 for ; Fri, 9 Sep 2005 11:36:55 -0300 (ADT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.13.1/8.13.1) with ESMTP id j89Eb0hg010448; Fri, 9 Sep 2005 10:37:00 -0400 (EDT) To: nikolay@samokhvalov.com Cc: pgsql-sql@postgresql.org Subject: Re: SELECT: retrieve only 2 rows next to known row In-reply-to: References: Comments: In-reply-to Nikolay Samokhvalov message dated "Fri, 09 Sep 2005 16:23:00 +0400" Date: Fri, 09 Sep 2005 10:37:00 -0400 Message-ID: <10447.1126276620@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.006 required=5 tests=[AWL=0.006] X-Spam-Level: X-Archive-Number: 200509/105 X-Sequence-Number: 22652 Nikolay Samokhvalov writes: > I don't know the position of this row in result set, but I want to > retrieve 2 rows that are next to this one. In general there is no such thing as "the row next to this one". SQL treats all data sets as unordered, up until the point where you do an explicit ORDER BY for display purposes. So your request is really meaningless unless you phrase it as "I want the rows that come immediately before and after this one in such-an-such an ordering". Once you do that, there is more than one way to solve the problem. For example, if the ordering you care about is on an indexed field, you could do something like SELECT * FROM tab WHERE foo > (SELECT foo FROM tab WHERE condition-to-select-reference-row) ORDER BY foo LIMIT 1 to get the following row, and SELECT * FROM tab WHERE foo < (SELECT foo FROM tab WHERE condition-to-select-reference-row) ORDER BY foo DESC LIMIT 1 to get the prior one (and if you really want just one query result, put these together with UNION ALL). Other solutions that come to mind involve cursors. You haven't told us enough about either the required ordering or the nature of the condition that defines "this row" to really say much about the best solution. regards, tom lane