swa*_*eck 22 postgresql parse sorting array
鉴于字符串:
'我认为 PostgreSQL 很漂亮'
我想对该字符串中找到的单个单词进行操作。本质上,我有一个单独的,我可以从中获取单词详细信息,并希望在此字典上加入该字符串的未嵌套数组。
到目前为止,我有:
select word, meaning, partofspeech
from unnest(string_to_array('I think that PostgreSQL is nifty',' ')) as word
from table t
join dictionary d
on t.word = d.wordname;
Run Code Online (Sandbox Code Playgroud)
这完成了我希望做的事情的基本原理,但它没有保留原始的词序。
Erw*_*ter 27
WITH ORDINALITY 在 Postgres 9.4 或更高版本中新功能简化了这类问题。上面的查询现在可以简单地为:
SELECT *
FROM regexp_split_to_table('I think Postgres is nifty', ' ') WITH ORDINALITY x(word, rn);Run Code Online (Sandbox Code Playgroud)
或者,应用于表:
SELECT *
FROM tbl t, regexp_split_to_table(t.my_column, ' ') WITH ORDINALITY x(word, rn);Run Code Online (Sandbox Code Playgroud)
细节:
关于隐式LATERAL连接:
您可以应用窗口函数row_number()来记住元素的顺序。但是,通常row_number() OVER (ORDER BY col)您会根据排序顺序获得数字,而不是字符串中的原始位置。
您可以简单地省略ORDER BY“按原样”获取位置:
SELECT *, row_number() OVER () AS rn
FROM regexp_split_to_table('I think Postgres is nifty', ' ') AS x(word);Run Code Online (Sandbox Code Playgroud)
regexp_split_to_table()长字符串的性能会下降。 unnest(string_to_array(...))更好地扩展:
SELECT *, row_number() OVER () AS rn
FROM unnest(string_to_array('I think Postgres is nifty', ' ')) AS x(word);Run Code Online (Sandbox Code Playgroud)
然而,虽然这通常有效并且我从未见过它在简单查询中中断,但 Postgres 在没有显式ORDER BY.
要保证原始字符串中元素的序号,请使用generate_subscript()(通过@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;Run Code Online (Sandbox Code Playgroud)
添加PARTITION BY id到OVER条款...
演示表:
CREATE TEMP TABLE strings(string text);
INSERT INTO strings VALUES
('I think Postgres is nifty')
,('And it keeps getting better');
Run Code Online (Sandbox Code Playgroud)
我用作主键ctid的临时替代品。如果您有一个(或任何唯一的列),请改用它。
SELECT *, row_number() OVER (PARTITION BY ctid) AS rn
FROM (
SELECT ctid, unnest(string_to_array(string, ' ')) AS word
FROM strings
) x;
Run Code Online (Sandbox Code Playgroud)
这在没有任何不同 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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19218 次 |
| 最近记录: |