? LIKE (column || '%')

余生颓废 提交于 2019-12-12 17:15:25

问题


Can I have a condition of something like this:

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

Where the ? is a string parameter value. For example, these parameter value ? should return true when column is equal to /admin/products

/admin/products/1
/admin/products/new
/admin/products/1/edit

Is this possible?

Update: Added test case.

Basically, the where clause would render like this:

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

But it always return false for me.

These queries works fine though:

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

The problem arises when I put the parameter ? before the LIKE clause. Is it not allowed?
If it's not, are there any workarounds for this?


回答1:


The query:

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

can be rewritten as (Postgres and MySQL):

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

As commented, the first form should work as well. It can be tricky, though, because characters with special meaning for LIKE (at least _%\) in the column would have to be escaped. If you want it to work with both MySQL and Postgres, you'll have to observe special characters in both implementations. So the 2nd form is much less error-prone on principal.

Performance

Neither of these queries can use an index on col, both are not sargable. The problem can be re-assessed as finding all possible prefixes to the given search pattern ?, which can be optimized in a similar fashion like in this related answer (for Postgres) on dba.SE:

  • Algorithm for finding the longest prefix



回答2:


Replacing

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

by

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

works for me.

Maybe || is used as logical or-operation instead of concatenation.




回答3:


Works for me.

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

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

returns true.

Your test case doesn't appear to accurately reflect the actual issue at hand.



来源:https://stackoverflow.com/questions/26989488/like-column

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!