PostgreSQL faz forneça funções dedicadas para gerar subscritos de matriz:
WITH x(a) AS ( VALUES ('{1,20,3,5}'::int[]) )
SELECT generate_subscripts(a, 1) AS idx
,unnest(a) AS val
FROM x;
Efetivamente, ele faz quase o mesmo que a consulta de @Frank, apenas sem subconsulta.
Além disso, funciona com subscritos que não começam com
1
. Qualquer solução funciona para 1-dimensional apenas matrizes! (Pode ser facilmente expandido para várias dimensões.)
Função:
CREATE OR REPLACE FUNCTION unnest_with_idx(anyarray)
RETURNS TABLE(idx integer, val anyelement) LANGUAGE SQL IMMUTABLE AS
$func$
SELECT generate_subscripts($1, 1), unnest($1);
$func$;
Ligar:
SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
Considere também:
SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
Mais sobre subscritos de matriz nesta pergunta relacionada.
Se você realmente quer subscritos normalizados (começando com 1), eu usaria:
SELECT generate_series(1, array_length($1,1)) ...
Essa é quase a consulta que você já tinha, apenas com
array_length()
em vez de array_upper()
- que falharia com subscritos não padrão. Desempenho
Fiz um teste rápido em um array de 1000 int com todas as consultas apresentadas aqui até agora. Todos eles têm o mesmo desempenho (~ 3,5 ms) - exceto
row_number()
em uma subconsulta (~ 7,5 ms) - como esperado, por causa da subconsulta. Atualização:Postgres 9.4+
A menos que você opere com subscritos de índice não padrão, use o novo
WITH ORDINALITY
em vez de:- PostgreSQL unnest() com número do elemento