怎么办'any(:: text [])ilike :: text'

时间:2011-03-21 11:15:09

标签: postgresql conditional-statements string-comparison any

这是表结构

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%'

无效。

2 个答案:

答案 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

上构建全文查询