WITH ORDINALITY dalam Postgres 9.4 atau lebih baru
Fitur baru menyederhanakan kelas masalah ini. Kueri di atas sekarang dapat berupa:
SELECT *
FROM regexp_split_to_table('I think Postgres is nifty', ' ') WITH ORDINALITY x(word, rn);
Atau, diterapkan pada tabel:
SELECT *
FROM tbl t, regexp_split_to_table(t.my_column, ' ') WITH ORDINALITY x(word, rn);
Detail:
Tentang LATERALgabung implisit :
Postgres 9.3 atau lebih tinggi - dan penjelasan yang lebih umum
Untuk satu string
Anda dapat menerapkan fungsi jendela row_number()untuk mengingat urutan elemen. Namun, dengan biasa row_number() OVER (ORDER BY col)Anda mendapatkan angka sesuai urutan , bukan posisi awal dalam string.
Anda bisa dengan mudah menghilangkan ORDER BYuntuk mendapatkan posisi "apa adanya":
SELECT *, row_number() OVER () AS rn
FROM regexp_split_to_table('I think Postgres is nifty', ' ') AS x(word);
Performa regexp_split_to_table()menurunkan dengan string panjang. unnest(string_to_array(...))skala lebih baik:
SELECT *, row_number() OVER () AS rn
FROM unnest(string_to_array('I think Postgres is nifty', ' ')) AS x(word);
Namun, sementara ini biasanya bekerja dan saya belum pernah melihatnya memecah dalam pertanyaan sederhana, Postgres tidak menegaskan apa pun tentang urutan baris tanpa eksplisit ORDER BY.
Untuk menjamin jumlah elemen dalam string asli, gunakan generate_subscript()(ditingkatkan dengan komentar oleh @deszo):
SELECT arr[rn] AS word, rn
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM string_to_array('I think Postgres is nifty', ' ') AS x(arr)
) y;
Untuk daftar string
Tambahkan PARTITION BY idke OVERklausa ...
Tabel demo:
CREATE TEMP TABLE strings(string text);
INSERT INTO strings VALUES
('I think Postgres is nifty')
,('And it keeps getting better');
Saya menggunakan ctidsebagai pengganti ad-hoc untuk kunci utama . Jika Anda memiliki satu (atau kolom unik ) gunakan saja.
SELECT *, row_number() OVER (PARTITION BY ctid) AS rn
FROM (
SELECT ctid, unnest(string_to_array(string, ' ')) AS word
FROM strings
) x;
Ini berfungsi tanpa ID berbeda:
SELECT arr[rn] AS word, rn
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM (
SELECT string_to_array(string, ' ') AS arr
FROM strings
) x
) y;
SQL Fiddle.
Jawab pertanyaan
SELECT z.arr, z.rn, z.word, d.meaning -- , partofspeech -- ?
FROM (
SELECT *, arr[rn] AS word
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM (
SELECT string_to_array(string, ' ') AS arr
FROM strings
) x
) y
) z
JOIN dictionary d ON d.wordname = z.word
ORDER BY z.arr, z.rn;