PostgreSQL robi zapewniają dedykowane funkcje do generowania indeksów tablicy:
WITH x(a) AS ( VALUES ('{1,20,3,5}'::int[]) )
SELECT generate_subscripts(a, 1) AS idx
,unnest(a) AS val
FROM x;
Skutecznie robi prawie to samo, co zapytanie @Frank, tylko bez podzapytania.
Dodatkowo działa z indeksami, które nie zaczynają się od 1
.
Każde rozwiązanie działa w przypadku jednowymiarowego tylko tablice! (Można łatwo rozszerzyć do wielu wymiarów.)
Funkcja:
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$;
Zadzwoń:
SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
Weź również pod uwagę:
SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
Więcej o indeksach tablicowych w tym powiązanym pytaniu.
Jeśli faktycznie chcesz znormalizowanych indeksów dolnych (zaczynających się od 1), użyłbym:
SELECT generate_series(1, array_length($1,1)) ...
To prawie zapytanie, które już miałeś, tylko z array_length()
zamiast array_upper()
- co zawiedzie z niestandardowymi indeksami dolnymi.
Wydajność
Przeprowadziłem szybki test na tablicy 1000 int ze wszystkimi przedstawionymi tutaj zapytaniami. Wszystkie działają mniej więcej tak samo (~ 3,5 ms) - z wyjątkiem row_number()
na podzapytanie (~ 7,5 ms) - zgodnie z oczekiwaniami, z powodu podzapytania.
Aktualizacja:Postgres 9.4+
Jeśli nie pracujesz z niestandardowymi indeksami indeksu, użyj nowego WITH ORDINALITY
zamiast tego:
- PostgreSQL unnest() z numerem elementu