Inline comments:

On Aug 15, 2012, at 16:24, David Greco <david_gr...@harte-hanks.com> wrote:

> Not sure how to write the CTE form of this. This query gives an error that 
> dave is missing a from clause entry.
> WITH o as (
>                 SELECT getRecord(1, dave.field1)
> )
> SELECT
>                 id, o.*
> FROM
>                 dave
> ;
>  
>  


With o (id, result) as (select id, getRecord(...) from dave)
Select id, (o.result).*
From dave
Left? Join o Using (id)


>  
> Regarding the INNER JOIN, actually it appears the opposite is true:
> SELECT
>                 id, generate_series(1, dave.field1)
> FROM
>                 Dave
> Works great if generate_series returns rows, but does not return any rows if 
> generate_series does not return rows (i.e. if dave has a row with 
> field1=null). So in fact, I need to figure out how to rewrite a LEFT JOIN 
> version of this query

Agreed.  See above example that can handle both.

>  
>  
> From: David Johnston [mailto:pol...@yahoo.com] 
> Sent: Wednesday, August 15, 2012 4:16 PM
> To: David Greco
> Cc: pgsql-general@postgresql.org
> Subject: Re: [GENERAL] Set Returning Functions and joins
>  
> On Aug 15, 2012, at 15:55, David Greco <david_gr...@harte-hanks.com> wrote:
> 
> I’m porting some code from an Oracle application and we have many uses of set 
> returning function. In particular, we are using them in joins of the form:
>  
> CREATE TABLE dave ( id integer, field1 integer );
> INSERT INTO dave VALUES (1, 10);
>  
> SELECT
>                 id, g.*
> FROM
>                 dave
>                 INNER JOIN generate_series( 1, dave.field1 ) ON (1=1)
>  
>  
> In reality, the examples are not trivial like this, and the set returning 
> function returns sets of records, not single values.
> Now, in the case of a LEFT JOIN and a function returning a setoff a simple 
> value, I can rewrite it simply as:
> SELECT
>                 id, generate_series(1, dave.field1)
> FROM
>                 dave
>  
>  
> In the case of a LEFT JOIN and  a function returning a setoff a record, I can 
> rewrite it as:
> SELECT
>                 id, ( getRecord(1, dave.field1) ).*
> FROM
>                 dave
>                                
>  
>  
> I then figured I can rewrite INNER JOINs as:
> SELECT
>                 id, ( getRecord(1, dave.field1) ).*
> FROM
>                 dave
> WHERE
>                 Exists ( SELECT 1 FROM getRecord(1, dave.field1) )
>  
> Though I suppose this is running getRecord once for every row in dave, then 
> another time for every row being returned.
>  
> Now in some non-trivial examples involving multiple joins on set returning 
> functions, this gets pretty complicated.
>  
>  
>  
>  
> Is there any alternative? Or I can suggest that a query the original form 
> should be allowed?
>  
> SELECT
>                 id, g.*
> FROM
>                 dave
>                 INNER JOIN generate_series( 1, dave.field1 ) ON (1=1)
>  
>  
> I suggest putting your function calls within a CTE (common table expression: 
> SQL command WITH) structure.
>  
> I do not get why you think you need an "EXISTS" in the INNER JOIN situation.  
> At worse you should make it a sub-query and add a IS NOT NULL condition on 
> one of the function result columns.  There is no way to avoid evaluating once 
> per record in dave but you should never have to evaluate more frequently than 
> that.  CTE and sub-selects are your friends.
>  
> The original form is currently being developed but will not be available 
> until at least 9.3
>  
> David J.
>  
>  
>  
>  
>  
>  

Reply via email to