2

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.

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

Comments

1

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+

Comments

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.