这是表结构
table1
pk int, email character varying(100)[]
data
1, {'mr_a@gmail.com', 'mr_b@yahoo.com', 'mr_c@postgre.com'}
我试图实现的是从记录中找到任何'gmail'
query
select * from table1 where any(email) ilike '%gmail%';
但 any()只能位于左侧,而 unexst()可能会降低性能。有谁有任何想法?
修改的
实际上,当我第一次发帖时,我有点混淆。我尝试通过 any(array [])来实现。
这是我的实际结构
pk int,
code1 character varying(100),
code2 character varying(100),
code3 character varying(100), ...
我的第一个approch是
select * from tabl1 where code1 ilike '%code%' or code2 ilike '%code%' or...
然后我尝试
select * from table1 where any(array[code1, code2, ...]) ilike '%code%'
无效。
答案 0 :(得分:5)
创建一个向后实现ILIKE
“的运算符,例如:
CREATE FUNCTION backward_texticlike(text, text) RETURNS booleans
STRICT IMMUTABLE LANGUAGE SQL
AS $$ SELECT texticlike($2, $1) $$;
CREATE OPERATOR !!!~~* (
PROCEDURE = backward_texticlike,
LEFTARG = text,
RIGHTARG = text,
COMMUTATOR = ~~*
);
(请注意,ILIKE
内部对应于运营商~~*
。请选择您自己的名称。)
然后你可以运行
SELECT * FROM table1 WHERE '%code%' !!!~~* ANY(ARRAY[code1, code2, ...]);
答案 1 :(得分:2)
将电子邮件地址存储在规范化表格结构中。然后,您可以避免unnest
的费用,拥有“正确的”数据库设计,并充分利用索引。如果您要进行全文式查询,则应将电子邮件地址存储在表格中,然后使用tsvector datatype,以便执行全文查询并使用索引。由于计划程序无法利用任何查询,ILIKE '%whatever%'
将导致全表扫描。根据您当前的设计和足够数量的记录,unnest
将是您最不担心的问题。
更新即使对问题进行了更新,使用规范化代码表也会让您头痛最少并导致最佳扫描。只要您发现自己创建了编号列,就可以很好地指示您可能需要进行标准化。话虽这么说,您可以创建计算文本列以用作搜索词列。在您的情况下,您可以创建一个search_words
列,该列在插入时填充并由触发器更新。然后,您可以创建tsvector
以在search_words