? LIKE(列||'%')

时间:2014-11-18 08:12:37

标签: mysql sql postgresql pattern-matching prefix

我可以遇到类似这样的情况:

SELECT * FROM table WHERE ? LIKE (column || '%')

?是字符串参数值。例如,当列等于?

时,这些参数值/admin/products 应返回true
/admin/products/1
/admin/products/new
/admin/products/1/edit

这可能吗?

更新:添加了测试用例。

基本上,where子句会像这样呈现:

1.  ? LIKE (column || '%')
2.  '/admin/products/1' like ('/admin/products' || %)
3.  '/admin/products/1' like ('/admin/products%')

但它总是对我不利。

但这些查询工作正常:

column = '/admin/products' --returns true
column = '/admin/products/1' --returns false
column LIKE '/admin/prod%' --returns true

当我将参数?放在LIKE子句之前时会出现问题。是不允许的?
如果不是,那有什么变通方法吗?

3 个答案:

答案 0 :(得分:2)

查询:

SELECT * FROM table WHERE ? LIKE (col || '%');

可以改写为(Postgres和MySQL):

SELECT * FROM table WHERE col = left(?, length(col));

如评论所述,第一种形式也应该有效。但是,这可能很棘手,因为列中LIKE(至少_%\具有特殊含义的字符必须进行转义。如果您希望它与MySQL和Postgres一起使用,那么您必须在两个实现中观察特殊字符。所以第二种形式是在主体上更不容易出错

性能

这两个查询都不能使用col上的索引,两者都不是sargable。可以将问题重新评估为找到给定搜索模式?的所有可能前缀,这些前缀可以像dba.SE上的相关答案(对于Postgres)类似的方式进行优化:

答案 1 :(得分:1)

更换

SELECT * FROM table WHERE ? LIKE (column || '%')

通过

SELECT * FROM table WHERE ? LIKE CONCAT(column, '%')

适合我。

也许||用作逻辑或操作而不是连接。

答案 2 :(得分:0)

适合我。

PREPARE withparam(text) AS SELECT $1 LIKE ('/admin/products' || '%');

EXECUTE withparam('/admin/products/1');

返回true。

您的测试用例似乎无法准确反映当前的实际问题。