I’m trying to create a parametric query that will be executed in a loop using plpgsql.
The 2 parameters will be the starting latitude/longitude points passed into the query. The latitude and longitude points will be retrieved from an array – so it will be a foreach like iteration over the array and to pass the two lat/lon values into the query for every execution.
How would I do something like this?
My query and the implementation way I thought is like the following: (the X,Z values are the parametric latitude/longitude values that will be passed, Y and T will be obtained by performing a certain calculation that I will handle). For clarity, my query returns multi-row and multi-columned results (timestamp and count) since it counts and returns the number of requests that fall into hour intervals(timestamps)
for each latitude-longitude pair X,Z in array
find Y and T from X and Z
WITH cal AS (
SELECT generate_series('2011-02-02 00:00:00'::timestamp ,
'2012-04-01 05:00:00'::timestamp ,
'1 hour'::interval) AS stamp
),
qqq AS (
SELECT date_trunc('hour', calltime) AS stamp, count(*) AS zcount
FROM mytable
WHERE calltime >= '2011-02-13 22:55:11'
AND calltime <= '2012-02-13 01:02:21'
AND (calltime::time >= '22:55:11'
OR calltime::time <= '01:02:21')
AND lat >= X
AND lat <= Y
AND lon >= Z
AND lon <= T
GROUP BY date_trunc('hour', calltime)
)
SELECT cal.stamp, COALESCE (qqq.zcount, 0) AS zcount
FROM cal
LEFT JOIN qqq ON cal.stamp = qqq.stamp
WHERE cal.stamp >= '2011-02-13 22:00:00'
AND cal.stamp <= '2012-02-13 01:02:21'
AND (
extract ('hour' from cal.stamp) >= extract ('hour' from '2011-02-13 22:00:00'::timestamp) or
extract ('hour' from cal.stamp) <= extract ('hour' from '2012-02-13 01:02:21'::timestamp)
)
ORDER BY stamp ASC;
Pass an array into the function and
FOR r IN SELECT * FROM unnest(the_array) LOOPover the elements in the array, whereris arecordvariable that’s in theDECLAREclause of the function; orLoop over a refcursor passed into the function. See PL/PgSQL cursors.
Even better, avoid the
LOOPand integrate theSELECT unnest(thearray)into your CTE. Loops in PL/PgSQL are much slower than the equivalent in a SQL CTE is likely to be.See
unnest,LOOP.