Received: from localhost (postgresql.org [64.49.215.8]) by postgresql.org (Postfix) with ESMTP id B985C475ABC for ; Fri, 9 Aug 2002 18:04:02 -0400 (EDT) Received: from lakemtao07.cox.net (lakemtao07.cox.net [68.1.17.114]) by postgresql.org (Postfix) with ESMTP id 684C8475A0E for ; Fri, 9 Aug 2002 18:03:57 -0400 (EDT) Received: from loki ([68.102.33.38]) by lakemtao07.cox.net (InterMail vM.5.01.04.05 201-253-122-122-105-20011231) with SMTP id <20020809220358.WIGI11447.lakemtao07.cox.net@loki>; Fri, 9 Aug 2002 18:03:58 -0400 From: "Adam Erickson" To: , Subject: Re: retrieving all rows from a "tree" in one select - how ? Date: Fri, 9 Aug 2002 17:04:23 -0500 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 Importance: Normal In-Reply-To: X-Virus-Scanned: by AMaViS new-20020517 X-Archive-Number: 200208/172 X-Sequence-Number: 9018 I'll be curious to see the responses to this. I myself deal with this same situation every day. Although we're currently using MySQL but moving it to postgres (which is why I'm on these lists..) > -- select a tree starting with node 1234 and all its descendants: > SELECT * FROM t WHERE id=1234 OR ANCESTOR(t.parent) IS 1234; I've seen some really weird solutions to this. I'm not sure if a subselect can do this or not. I doubt it. Since MySQL limits us greatly we resort to a lookup field for each record in the node. ie. (Forgive ASCII art please) 1 --> 2 --> 4 --> 5 --> 6 --> 8 --> 9 --> 3 --> 7 --> 10 The record for id=9 would have a field index='-1-2-6-8-x' When we want all records under node id=6 we just use: select * from t where index like "%-6-%"; We prefix with '-' for arbitrary level searches. We suffix with -x for an unknown (but good) reason. My memory is leaving me. > -- select the path from tree node 2345 to the root > SELECT * FROM t WHERE id=2345 OR DESCENTANT(t.parent) IS 2345; With our lookup/index field this is trivial. Unfortunately, it makes the application responsible for parsing and is probably not what you're after. Just my two cents. It works very well for us (make the lookup field an index btw) but their is probably a much better way in postgres. I don't remember if postgres allows regexes in the where clause (ie. rlike in mysql) but with that you can "find all nodes 3 or more leaves down from node 123" or even weirder stuff. We have trees with 60,000 nodes 30-40 levels deep. Queries on the tree take very little time at all. Adam Erickson