我在PostgreSQL中有一个用于存储电影细节的表,
film_id serial NOT NULL,
title text,
language text,
directors text[]
我可以写一个查询来查找所有具有导演姓名' ab'
的电影SELECT * FROM films where 'ab' like any(films.directors)
但是如何编写一个查询来搜索表格以获得所有电影的导演名称以' ab'开头,此查询不会给我任何结果
SELECT * FROM films where 'ab%' like any(films.directors)
答案 0 :(得分:1)
我可以想到两种不同的方式(它们都不是很优雅):
取消数组,然后使用LIKE
搜索元素,如果您需要再次将结果作为数组,则需要进行聚合(这意味着添加的列数不仅仅是导向器和film_id
会很复杂:
select film_id, array_agg(name) as directors
from (
SELECT film_id, unnest(directors) as name
FROM films
) t
where name like 'ab%'
group by film_id;
另一个选项(同样慢)可能是创建一个带有分隔符的长字符串,然后在该字符串中搜索:
select *
from films
where '###'||array_to_string(directors, '###') like '%###ab%'
将分隔符预先添加到字符串中可确保每个条目都以分隔符开头,条件like '%###ab%'
仅匹配实际以ab
开头的名称。
答案 1 :(得分:1)
还有另一种方式。原因是,您的原始计划无效,原因是array comparison expressions只能使用运算符&运算符右侧的数组表达式:
<expression> operator ANY|SOME|ALL (<array expression>)
所有模式匹配运算符都工作颠倒(右侧有模式) - 你也可以使用它,但只有你有一个模式数组,你要测试它又一个字符串。这通常不是那么有用,但你可以make some operators反转:
CREATE OR REPLACE FUNCTION reverse_like(text, text) RETURNS BOOLEAN LANGUAGE SQL AS 'SELECT $2 LIKE $1';
CREATE OR REPLACE FUNCTION reverse_ilike(text, text) RETURNS BOOLEAN LANGUAGE SQL AS 'SELECT $2 ILIKE $1';
CREATE OR REPLACE FUNCTION reverse_similarto(text, text) RETURNS BOOLEAN LANGUAGE SQL AS 'SELECT $2 SIMILAR TO $1';
CREATE OR REPLACE FUNCTION reverse_posix_match(text, text) RETURNS BOOLEAN LANGUAGE SQL AS 'SELECT $2 ~ $1';
CREATE OR REPLACE FUNCTION reverse_posix_imatch(text, text) RETURNS BOOLEAN LANGUAGE SQL AS 'SELECT $2 ~* $1';
CREATE OPERATOR ~~> (PROCEDURE = reverse_like, LEFTARG = text, RIGHTARG = text);
CREATE OPERATOR ~~*> (PROCEDURE = reverse_ilike, LEFTARG = text, RIGHTARG = text);
CREATE OPERATOR ~~~> (PROCEDURE = reverse_similarto, LEFTARG = text, RIGHTARG = text);
CREATE OPERATOR ~> (PROCEDURE = reverse_posix_match, LEFTARG = text, RIGHTARG = text);
CREATE OPERATOR ~*> (PROCEDURE = reverse_posix_imatch, LEFTARG = text, RIGHTARG = text);
之后,您可以使用ANY
/ SOME
/ ALL
数组比较:
SELECT *
FROM films
WHERE '^ab' ~> any(films.directors);
SELECT *
FROM films
WHERE 'ab%' ~~> any(films.directors);
SELECT *
FROM films
WHERE 'ab%' ~~~> any(films.directors);
答案 2 :(得分:0)
SELECT *
FROM films
where directors like 'ab%';
应该能满足您的要求。注意LIKE
运算符的表达式是如何从它们所在的顺序切换的。
这是postgresql 9的SELECT
文档的link,其中有一个查询示例,如上例所示。
ANY
需要根据http://www.postgresql.org/docs/9.0/static/functions-subquery.html