Pregunta

I need to convert from an array to rows and back to an array for filtering records. I'm using information_schema._pg_expandarray in a SELECT query to get one row per value in the array.

Given the following array :

"char"[]
{i,i,o,t,b}

_pg_expandarray retuns 5 rows with 1 column of type record :

record
(i,1)
(i,2)
(o,3)
(t,4) <= to be filtered out later
(b,5)

I need to filter this result set to exclude record(s) that contains 't'.

How can I do that ? Should I convert back to an array ? Is there a way to filter on the array directly ?

Thanks in advance.

¿Fue útil?

Solución

If your objective is to produce a set of rows as above but with the row containing 't' removed, then this does the trick:

test=> select * 
       from  information_schema._pg_expandarray(array['i','i','o','t','b']) as a(i)
       where a.i!='t';
 i | n
---+---
 i | 1
 i | 2
 o | 3
 b | 5
(4 rows)

As an aside, unless you particularly want the index returned as a second column, I'd be inclined to use unnest() over information_schema._pg_expandarray(), which does not appear to be documented and judging by the leading '_' in the name is probably intended for internal usage.

There does not seem to be any built in function to filter arrays. Your question implies you may want the result in array form - if that is the case then writing a simple function is trivial. Here is an example:

CREATE OR REPLACE FUNCTION array_filter(anyarray, anyelement) RETURNS anyarray
AS $$
DECLARE
   inArray ALIAS FOR $1;
   filtValue ALIAS FOR $2;
   outArray ALIAS FOR $0;
   outIndex int=0;
BEGIN
   FOR I IN array_lower(inArray, 1)..array_upper(inArray, 1) LOOP
    IF inArray[I] != filtValue THEN
        outArray[outIndex] := inArray[I];
        outIndex=outIndex+1;
    END IF;
   END LOOP;
RETURN outArray;
END;
$$ LANGUAGE plpgsql 
STABLE 
RETURNS NULL ON NULL INPUT;

Usage:

test=> select array_filter(array['i','i','o','t','b'],'t');
  array_filter
-----------------
 [0:3]={i,i,o,b}
(1 row)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top