Re: Recursive queries? - Mailing list pgsql-hackers
From | Christopher Browne |
---|---|
Subject | Re: Recursive queries? |
Date | |
Msg-id | m3brofouql.fsf@wolfe.cbbrowne.com Whole thread Raw |
In response to | Recursive queries? (Christopher Kings-Lynne <chriskl@familyhealth.com.au>) |
Responses |
Re: Recursive queries?
|
List | pgsql-hackers |
Clinging to sanity, ronz@ravensfield.com (Andrew Rawnsley) mumbled into her beard: > I haven't had any problems with it so far, although I haven't really > stressed it yet. I was going to make this very plea... > > I agree that the syntax can probably be improved, but its familiar to > those of us unfortunate enough to have used (or still have to use) > Oracle. I imagine that bringing it more in line with any standard > would be what people would prefer. The SQL:1999 form is instead of the form with recquery (a,b,c,d) as (select a1,b1,c1,d1 from some table where d1 > 21) select * from recquery; Notice that I have indented this in the same way a Lisp programmer would indent a LET form... (let ((a value-for-a) (b value-for-b) (c compute-c) (d 42)) ;;; The ultimate answer... (compute-something-with-valuesa b c d)) In ML, there is an analagous "let/in" construct: #let a = 1 and b = 2 and c = 3 in a + b * c;; - : int = 7 That example is oversimplified, a bit, as it does not do anything recursive. In order to express a recursive relationship, the query likely needs to have a UNION ALL, and look more like the following: with recquery (a,b,c,d) as (select a,b,c,d from base_table root -- Root level entries where c > 200 union all select child.a,child.b,child.c,child.d from recquery parent, base_table child -- Self-reference here where parent.a= child.b -- The link between nodes... and c > 200) select a,b,c,d from recquery; The fact that the form of this resembles that of the Lisp/ML "let" forms means that WITH can be useful in structuring queries as well. For instance, supposing you're computing a value that gets used several times, putting it into a WITH clause might allow evading the need to compute it more than once. with notrec (radius, pi, month) as (select radius, 3.1412, date_trunc('month', txn_date) from pie_table)select month, sum(pi* radius * radius as area), count(*) from not_rec where month between '2003-01-01' and '2004-01-01' group by month; has some 'elegance' by virtue of only using date_trunc once over select date_trunc('month', txn_date), sum(3.1412 * radius*radius) as area, count(*) from pie_table where date_trunc('month',txn_date) between '2003-01-01' and '2004-01-01' group by month; Admittedly, date_trunc() may not be an ideal example, as the date constraint would work as well with an untruncated date the point is that in the no-WITH approach, there is an extra use of date_trunc(). But the recomputation that takes place when a functional value is used both in the result clause and in the WHERE clause is something that WITH can eliminate. -- "aa454","@","freenet.carleton.ca" http://www.ntlug.org/~cbbrowne/emacs.html Lisp Users: Due to the holiday next Monday, there will be no garbage collection.
pgsql-hackers by date: