PostgreSQL bisa menyediakan fungsi khusus untuk menghasilkan subskrip larik:
WITH x(a) AS ( VALUES ('{1,20,3,5}'::int[]) )
SELECT generate_subscripts(a, 1) AS idx
,unnest(a) AS val
FROM x;
Secara efektif ia melakukan hampir sama dengan kueri @Frank, hanya tanpa subkueri.
Selain itu, ia bekerja dengan subskrip yang tidak dimulai dengan 1
.
Salah satu solusi berfungsi untuk 1-dimensi array saja! (Dapat dengan mudah diperluas ke beberapa dimensi.)
Fungsi:
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$;
Telepon:
SELECT * FROM unnest_with_idx('{1,20,3,5}'::int[]);
Pertimbangkan juga:
SELECT * FROM unnest_with_idx('[4:7]={1,20,3,5}'::int[]);
Selengkapnya tentang subskrip larik dalam pertanyaan terkait ini.
Jika Anda sebenarnya ingin subskrip yang dinormalisasi (dimulai dengan 1), saya akan menggunakan:
SELECT generate_series(1, array_length($1,1)) ...
Itu hampir kueri yang sudah Anda miliki, hanya dengan array_length()
bukannya array_upper()
- yang akan gagal dengan subskrip non-standar.
Kinerja
Saya menjalankan tes cepat pada array 1000 int dengan semua kueri yang disajikan di sini sejauh ini. Semuanya bekerja hampir sama (~ 3,5 mdtk) - kecuali untuk row_number()
pada subkueri (~ 7,5 md) - seperti yang diharapkan, karena subkueri.
Pembaruan:Postgres 9.4+
Kecuali Anda beroperasi dengan subskrip indeks non-standar, gunakan WITH ORDINALITY
baru sebagai gantinya:
- PostgreSQL unnest() dengan nomor elemen