For a single string
You can apply the window function row_number() to remember a distinct order of elements. However, with the usual row_number() OVER (ORDER BY col) you get numbers according to the sort order, not the ordinal number of the original position in the string.
You could try and simply omit the ORDER BY to get the position "as is":
SELECT *, row_number() OVER () AS rn
FROM (
SELECT regexp_split_to_table('I think postgres is nifty', ' ') AS word
) x;
Performance of regexp_split_to_table() degrades with long strings. unnest(string_to_array(...)) scales better:
SELECT *, row_number() OVER () AS rn
FROM (
SELECT unnest(string_to_array('I think postgres is nifty', ' ')) AS word
) x;
However, while this works normally, and I have never seen it break in simple queries, PostgreSQL asserts nothing concerning the order of rows without explicit ORDER BY.
To guarantee row numbers matching the ordinal number of the element in the string:
SELECT arr[rn] AS word, rn
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM (
SELECT string_to_array('I think postgres is nifty', ' ') AS arr
) x
) y;
http://www.postgresql.org/docs/current/interactive/functions-srf.html#FUNCTIONS-SRF-SUBSCRIPTS
For a table of strings
Add PARTITION BY id to the OVER clause ..
Demo table:
CREATE TEMP TABLE strings(string text);
INSERT INTO strings VALUES
('I think postgres is nifty')
,('And it keeps getting better');
I use ctid as ad-hoc pk substitute. If you have a primary key or any unique column available use that instead.
SELECT *, row_number() OVER (PARTITION BY ctid) AS rn
FROM (
SELECT ctid, unnest(string_to_array(string, ' ')) AS word
FROM strings
) x;
This works without any distinct ID:
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
-> sqlfiddle.
Answer to question
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;