Reputation: 31191
The following code snippet creates three arrays, which are passed into a PL/R function.
FOR s_id, s_latitude, s_longitude IN
SELECT
s.id,
s.latitude_decimal,
s.longitude_decimal
FROM
climate.station s
WHERE
s.applicable AND
s.latitude_decimal BETWEEN box.latitude_min AND box.latitude_max AND
s.longitude_decimal BETWEEN box.longitude_min AND box.longitude_max
LOOP
SELECT array_append( v_id, s_id ) INTO v_id;
SELECT array_append( v_latitude, s_latitude ) INTO v_latitude;
SELECT array_append( v_longitude, s_longitude ) INTO v_longitude;
END LOOP;
The arrays are declared as:
v_id integer[];
v_latitude double precision[];
v_longitude double precision[];
I would rather use CREATE TYPE
and pass one array with each element containing three values.
How would you code this so that it does not use a FOR ... LOOP
?
The first line of the PL/R function is:
stations <- cbind( v_id, v_longitude, v_latitude )
I would like to eliminate that line of code and simplify the SELECT
query.
Thank you.
Upvotes: 2
Views: 944
Reputation: 7705
According to the pl/r documentation, "...two-dimensional PostgreSQL arrays are mapped to R matrixes..."
Maybe something like...
SELECT
plr_function(
array_agg(array[s.id,s.latitude_decimal,s.longitude_decimal])
)
FROM
climate.station s
WHERE
s.applicable AND
s.latitude_decimal BETWEEN box.latitude_min AND box.latitude_max AND
s.longitude_decimal BETWEEN box.longitude_min AND box.longitude_max
Upvotes: 1
Reputation: 622
You could use the following code and continue using 3 arrays:
SELECT
array_agg(s.id),
array_agg(s.latitude_decimal),
array_agg(s.longitude_decimal)
INTO
v_id, v_latitude, v_longitude
FROM
climate.station s
WHERE
s.applicable AND
s.latitude_decimal BETWEEN box.latitude_min AND box.latitude_max AND
s.longitude_decimal BETWEEN box.longitude_min AND box.longitude_max
or use the row constructor and assemble an array of a composite type:
SELECT
array_agg((
s.id,
s.latitude_decimal,
s.longitude_decimal
))
INTO
v_id, v_latitude, v_longitude
FROM
climate.station s
WHERE
s.applicable AND
s.latitude_decimal BETWEEN box.latitude_min AND box.latitude_max AND
s.longitude_decimal BETWEEN box.longitude_min AND box.longitude_max
BTW, this will only work on PostgreSQL 8.4+
Upvotes: 1