Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 866F0B60750 for ; Sun, 5 Jun 2011 16:43:12 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 05953-08 for ; Sun, 5 Jun 2011 19:43:05 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from eastrmfepo203.cox.net (eastrmfepo203.cox.net [68.230.241.218]) by mail.postgresql.org (Postfix) with ESMTP id CDFC6B6074E for ; Sun, 5 Jun 2011 16:43:04 -0300 (ADT) Received: from eastrmimpo03.cox.net ([68.1.16.126]) by eastrmfepo203.cox.net (InterMail vM.8.01.04.00 201-2260-137-20101110) with ESMTP id <20110605194258.VSI32702.eastrmfepo203.cox.net@eastrmimpo03.cox.net> for ; Sun, 5 Jun 2011 15:42:58 -0400 Received: from slacker.ja10629.home ([68.106.109.147]) by eastrmimpo03.cox.net with bizsmtp id sKis1g0093Ar1Vg02KisPs; Sun, 05 Jun 2011 15:42:58 -0400 X-CT-Score: 0.00 X-CT-RefID: str=0001.0A020201.4DEBDC42.00AD,ss=1,re=0.000,fgs=0 X-CT-Spam: 0 X-Authority-Analysis: v=1.1 cv=DkLg0PgY2o4lZqvIebXfT14XCAMsRf7aiPsXd65v5So= c=1 sm=1 a=z1TLwsU0kBEA:10 a=rNODZyWf3PYA:10 a=PjkiJtDTOQ4A:10 a=ZcFhQy0-F_sA:10 a=kj9zAlcOel0A:10 a=sXZhTwfwSKhiTs9RzZXpNQ==:17 a=P6M1L9rJAAAA:8 a=epTmVMiNAAAA:8 a=t4RSRZfXWX9QfKgagKMA:9 a=4tEzcgWVfTJ-PVgrfaEA:7 a=CjuIK1q_8ugA:10 a=V_iEmhlNuOsA:10 a=YObXiYvaVLwA:10 a=sXZhTwfwSKhiTs9RzZXpNQ==:117 X-CM-Score: 0.00 Authentication-Results: cox.net; none Received: from wcuddy by slacker.ja10629.home with local (Exim 4.72) (envelope-from ) id 1QTJDo-0000pX-3p for pgsql-sql@postgresql.org; Sun, 05 Jun 2011 15:42:52 -0400 Date: Sun, 5 Jun 2011 15:42:52 -0400 From: lists-pgsql@useunix.net To: pgsql-sql@postgresql.org Subject: Re: selecting records X minutes apart Message-ID: <20110605194252.GD16254@slacker.ja10629.home> References: <20110603195253.GE1324@slacker.ja10629.home> <20110605205228.950A.2D56284C@amail.plala.or.jp> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110605205228.950A.2D56284C@amail.plala.or.jp> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.9 tagged_above=-5 required=5 tests=BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001 X-Spam-Level: X-Archive-Number: 201106/20 X-Sequence-Number: 35486 Thank you all who replied!! It looks like Sugawara's recursive solution does the trick. Unfortunately performance is quite poor for the sample dataset I'm working with which is a table of about 50000 records. Indeed, there are indexes applied to the table. I believe the recursive select is being executed a great number of times causing the first part of the query to take a long time. The fastest solution I've come up with is a plpgsql procedure the loops over a select where the result is ordered by (id,tstamp) and examines the tstamp values and only returns rows that meet the interval criteria. This technique takes roughly 2 seconds to filter out records over my 50000 record sample set.... which is acceptable but not nearly as elegant as a single SQL statement. Again, thank you for all the replies. Wayne On Sun, Jun 05, 2011 at 08:52:30PM +0900, Masaru Sugawara wrote: > On Fri, 3 Jun 2011 15:52:53 -0400 > lists-pgsql@useunix.net wrote: > > > I also think you might want to use WITH RECURSIVE clause. > This SQL searches the case of an interval of 5 minutes or more, > and sets a relationship between a parent to its child. > > > CREATE TABLE tbl(id integer, ts time) ; > INSERT INTO tbl VALUES > (0, '20:00'), > (0, '20:05'), > (0, '20:08'), > (0, '20:10'), > (0, '20:11'), > (1, '20:03'), > (1, '20:04'), > (1, '20:05'), > (1, '20:09'), > (1, '20:16'); > > SELECT * FROM tbl; > > > -- > WITH RECURSIVE rec(id , ts_p, ts_c) AS ( > SELECT a1.id, min(a1.ts), min(b1.ts) > FROM tbl AS a1, tbl AS b1 > WHERE a1.id=b1.id AND a1.ts + interval'5 minute' <= b1.ts > GROUP BY a1.id > UNION ALL > SELECT t2.id, t2.ts_p, t2.ts_c > FROM rec AS t1 INNER JOIN > (SELECT a2.id, a2.ts as ts_p, min(b2.ts) AS ts_c > FROM tbl AS a2, tbl AS b2 > WHERE a2.id = b2.id AND a2.ts + interval'5 minute' <= b2.ts > GROUP BY a2.id, a2.ts > UNION ALL > SELECT a3.id, a3.ts, null > FROM tbl AS a3 > ) AS t2 ON t1.id = t2.id AND t1.ts_c=t2.ts_p > ) > SELECT DISTINCT id, ts_p AS ts FROM rec > ORDER BY 1,2; > > > > > > > > I have a table that, at a minimum, has ID and timestamp columns. Records > > are inserted into with random IDs and timestamps. Duplicate IDs are allowed. > > > > I want to select records grouped by ID, ordered by timestamp that are X minutes > > apart. In this case X is 5. > > > > Note, the intervals are not X minute wall clock intervals, they are X minute > > intervals from the last accepted record, per-id. > > > > For instance here is some sample input data: > > > > ID TS (HH:MM) > > ------------------- > > 0 20:00 > > 1 20:03 > > 1 20:04 > > 0 20:05 > > 1 20:05 > > 0 20:08 > > 1 20:09 > > 0 20:10 > > > > I'd want the select to return: > > > > ID TS (HH:MM) > > ------------------- > > 0 20:00 > > 0 20:05 > > 0 20:10 > > 1 20:03 > > 1 20:09 > > > > > > Does my question make sense? > > > > Thanks in advance, > > Wayne > > > > -- > > Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) > > To make changes to your subscription: > > http://www.postgresql.org/mailpref/pgsql-sql > > > > > -- > Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-sql