# stubs for FactoryGirl's magic methods for Rubymine
def create(*_args) end
def create_list(*_args) end
def build(*_args) end
def build_stubbed(*_args) end
我在下面的查询中使用了它,但是它没有返回任何输出:
create table x_a (id1 integer, shared text);
create table x_b (id1 integer, shared text);
insert into x_a values
(1, 'A,B,C,D,E')
, (2, 'A,B,C,D,E');
insert into x_b values
(1, 'B,A,C,E,D')
, (2, 'B,A,C,E');
我无法使用运算符select a.id1,b.id1, a.shared, b.shared
from x_a a ,x_b b
where a.id1 = b.id1
and regexp_split_to_array(LOWER(a.shared),',')
= regexp_split_to_array(LOWER(b.shared),',')
,因为它将返回&&
,这是错误的,因为“共享”列不是确切的副本。
答案 0 :(得分:2)
我无法使用运算符
&&
,因为它将返回id=2
,这是错误的...
但是您可以像这样使用array operators @>
and <@
:
SELECT id1, a.shared AS a_shared, b.shared AS b_shared
FROM x_a a
JOIN x_b b USING (id1)
WHERE string_to_array(a.shared, ',') @> string_to_array(b.shared, ',')
AND string_to_array(a.shared, ',') <@ string_to_array(b.shared, ',');
如果A包含B,而B包含A,则两者都是等于-忽略重复项。
您可能想存储(排序的)数组开头-或通过1:n关系规范化数据库设计。
如果您的元素是integer
数字,请考虑使用附加的intarray模块以获得更好的性能。参见:
答案 1 :(得分:0)
数组=
取决于元素的顺序,因此在将元素变成数组时需要对元素进行排序。我认为最简单的方法是使用自己的功能。
create function string_to_array_sorted(p_input text)
returns text[]
as
$$
select array_agg(t.x order by t.x)
from unnest(string_to_array(lower(p_input), ',')) as t(x);
$$
language sql
immutable;
请注意,如果不需要正则表达式,string_to_array()
的效率要比regexp_split_to_array()
高。
使用上述功能,您的查询可以写为:
select a.id1,b.id1, a.shared, b.shared
from x_a a
join x_b b on a.id1 = b.id1
where string_to_array_sorted(a.shared) = string_to_array_sorted(b.shared);
请注意,我用一个“现代”(已有30年历史)的显式JOIN
运算符替换了古老,过时且脆弱的隐式连接。
您可以创建索引来加快速度:
create index on x_a (id1, string_to_array_sorted(shared));
create index on x_b (id1, string_to_array_sorted(shared));