Duc*_*ong 4 sql arrays postgresql
我正在构建一种字典应用程序,我有一个用于存储以下单词的表:
id | surface_form | examples
-----------------------------------------------------------------------
1 | sounds | {"It sounds as though you really do believe that",
| | "A different bell begins to sound midnight"}
Run Code Online (Sandbox Code Playgroud)
surface_formtype 在哪里CHARACTER VARYING,examples是一个数组字段CHARACTER VARYING
由于示例是从另一个API自动生成的,因此它可能不包含确切的"surface_form".现在我想在示例中仅保留包含确切surface_form的句子.例如,在给定的示例中,只保留第一个句子,因为它只包含sounds第二个句子sound.
问题是我陷入了如何编写查询和/或plSQL存储过程来更新examples列,以便它只有所需的句子.
此查询会跳过不需要的数组元素:
select id, array_agg(example) new_examples
from a_table, unnest(examples) example
where surface_form = any(string_to_array(example, ' '))
group by id;
id | new_examples
----+----------------------------------------------------
1 | {"It sounds as though you really do believe that"}
(1 row)
Run Code Online (Sandbox Code Playgroud)
用于update:
with corrected as (
select id, array_agg(example) new_examples
from a_table, unnest(examples) example
where surface_form = any(string_to_array(example, ' '))
group by id
)
update a_table
set examples = new_examples
from corrected
where examples <> new_examples
and a_table.id = corrected.id;
Run Code Online (Sandbox Code Playgroud)
在rextester中测试它.
小智 5
也许你必须改变表设计.这就是PostgreSQL的文档中关于数组使用的说法:
数组不是集合; 搜索特定的数组元素可能是数据库错误设计的标志.考虑为每个将成为数组元素的项使用一个单独的表.这将更容易搜索,并且可能更好地扩展到大量元素.
文档:https: //www.postgresql.org/docs/current/static/arrays.html
小智 2
最紧凑的解决方案(但不一定是最快的)是编写一个函数,传递一个正则表达式和一个数组,然后返回一个仅包含与正则表达式匹配的项目的新数组。
create function get_matching(p_values text[], p_pattern text)
returns text[]
as
$$
declare
l_result text[] := '{}'; -- make sure it's not null
l_element text;
begin
foreach l_element in array p_values loop
-- adjust this condition to whatever you want
if l_element ~ p_pattern then
l_result := l_result || l_element;
end if;
end loop;
return l_result;
end;
$$
language plpgsql;
Run Code Online (Sandbox Code Playgroud)
该if条件仅是示例。您需要将其调整为您确切存储在surface_form列中的内容。也许您需要测试正则表达式的单词边界,或者一个简单的instr()就可以了 - 您的问题对此不清楚。
清理表格就变得非常简单:
update the_table
set examples = get_matching(examples, surface_form);
Run Code Online (Sandbox Code Playgroud)
但整个方法对我来说似乎有缺陷。如果将示例存储在适当规范化的数据模型中,效率会高得多。
| 归档时间: |
|
| 查看次数: |
723 次 |
| 最近记录: |