0

I've got a PL/pgSQL function that return a table whose definition is as follows:

CREATE OR REPLACE FUNCTION get_movement_aggregation(movement_table varchar,place_table varchar,geom varchar,point_gid varchar, radius numeric DEFAULT 20000, inArea geometry DEFAULT NULL)
RETURNS TABLE(place_i integer) AS
-- actual code here

Now I would like to use this function by using a geometry (the inArea parameter) that I get from another table. When I try the following query:

WITH x AS (
  SELECT wkb_geometry from tha_adm1 
  WHERE name_1 = 'Ubon Ratchathani' LIMIT 1
)
SELECT g.* 
FROM x,
get_movement_aggregation('movements','places','geom','place_id',14000,x.wkb_geometry)

I get the following error:

ERROR: function expression in FROM cannot refer to other relations of same query level

It does make sense as I indeed refer to x in both parts of the FROMclause.

The subquery returns the following:

+----------------------------------+
|   |  wkb_geometry                |
|   |  geometry(MultiPolygon,4326) |
+---+------------------------------+
| 1 | some very long number here   |
+---+------------------------------+

And I just use this parameter to filter the list of records I am working with in the function. One solution would be to create a temporary table with the filtered records and feed to the function but if there is a way to do that with a subquery, that would be great.

Thank you in advance for your answers.

1

2 Answers 2

2

Why not this:

WITH x AS (
  SELECT wkb_geometry from tha_adm1 
  WHERE name_1 = 'Ubon Ratchathani' LIMIT 1
)
SELECT 
get_movement_aggregation('movements','places',
                         'geom','place_id',14000,x2.wkb_geometry)
FROM (SELECT * FROM x) as x2

Or a simpler form, without the WITH clause:

SELECT 
get_movement_aggregation('movements','places',
                         'geom','place_id',14000,x2.wkb_geometry)
FROM (SELECT wkb_geometry from tha_adm1 
  WHERE name_1 = 'Ubon Ratchathani' LIMIT 1) as x2

Or if you prefer to have explicit fields rather than a function call in the final select list:

SELECT g.* FROM 
 (SELECT get_movement_aggregation('movements','places',
                                  'geom','place_id',14000,x2.wkb_geometry)
    FROM (SELECT wkb_geometry from tha_adm1 
           WHERE name_1 = 'Ubon Ratchathani' LIMIT 1) as x2
 ) as g;
Sign up to request clarification or add additional context in comments.

1 Comment

Answer accepted. So the trick was to put the function call in the SELECT... Was not really familiar with functions returning tables. Merci mille fois!!!
1

This form of the query is called LATERAL in the SQL standard. Support for such queries will be available in PostgreSQL 9.3, you can find an excellent review here by @depesz.

Before that you will have to use subqueries, @Daniel outlined a bunch of possibilities.

1 Comment

Yeah, I've read this on another answer and I've read the review too. Thank you! @Daniel helped to get the result I wanted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.