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 LATERAL
gabung 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 BY
untuk 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 id
ke OVER
klausa ...
Tabel demo:
CREATE TEMP TABLE strings(string text);
INSERT INTO strings VALUES
('I think Postgres is nifty')
,('And it keeps getting better');
Saya menggunakan ctid
sebagai 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;