MySQL中find_in_set(value,set)的sqlite中的等效函数是什么?

时间:2011-10-28 06:50:44

标签: sql sqlite

以下示例是w.r.t MySQL。 例如:test1如下

+----+------------------------+
| id | name                   |
+----+------------------------+
|  2 | 1,2                    |
| 33 | 2,44,33,5              |
|  1 | 11,4,55                |
| 12 | 11,111,122,551,112,221 |
+----+------------------------+

选择* 来自test1 其中find_in_set('122',名称)

将进行以下操作:

+----+------------------------+
| id | name                   |
+----+------------------------+
| 12 | 11,111,122,551,112,221 |
+----+------------------------+

在Sql Lite中,使用它会是:

select * 
from `test1` 
where name like '%,122,%'
or name like '122,%'
or name like '%,122'
or name = '122'
  

案例:

我的价值是551,122。在这种情况下,当从appln返回值时,我们可以拆分值列&将查询写为

(',' || column_name || ',') LIKE '%,551,%' or
(',' || column_name || ',') LIKE '%,122,%'

任何最好的想法来处理这个问题?

我想避免喜欢。那么还有其他想法吗?

3 个答案:

答案 0 :(得分:5)

我的第一个想法是你不应该将CSV数据存储在关系数据库的一列中,你应该使用一个单独的关联表。

你可以使用LIKE来完成这项工作。您的评论表明您看到了三种情况,但实际上有四种情况:

select *
from test1
where name like '122,%'
   or name like '%,122'
   or name like '%,122,%'
   or name    = '122'     /* You forgot about this degenerate case */

索引可以用于最后一种情况,也可能用于第一种情况,但中间两种可能是表扫描。如果强制数据始终具有前导和尾随逗号,则可以简化查询:

+----+--------------------------+
| id | name                     |
+----+--------------------------+
|  2 | ,1,2,                    |
| 33 | ,2,44,33,5,              |
|  1 | ,11,4,55,                |
| 12 | ,11,111,122,551,112,221, |
+----+--------------------------+

然后你只能使用一个LIKE(不会使用索引):

select *
from test1
where name like '%,122,%'

但你真的应该使用一个关联表,以便你可以使用where name = 122并加入其他表来完成其余的工作。

答案 1 :(得分:0)

我更喜欢采用John Weldon提到的策略,

所以,

select *
from test1
where (',' || column_name || ',') LIKE '%,122,%' //any value 

Reference

答案 2 :(得分:0)

创建一个功能

public class ConnectionOpenHandler extends Interceptor{
  private static final long serialVersionUID=1;
  private String nameConnection;
  private String jdbcUrl;

  public void handler(Handler handler) throws Exception{
    Context context=(Context)handler.getProperty("context");
    SessionContext sessionContext=(SessionContext)context;

    Class.forName("org.sqlite.JDBC");
    Connection connection=DriverManager.getConnection(jdbcUrl);
    connection.setAutoCommit(false);
    handler.setProperty(nameConnection,connection);
    sessionContext.getProtectedContext().setProperty(nameConnection,connection);

    Function.create(connection,"find_in_set",new FindInSet());
  }
  private class FindInSet extends Function{
    protected void xFunc() throws SQLException{
      String row=this.value_text(0);
      String values=this.value_text(1);

      if(values==null){
        result(0);
        return;
      }

      boolean ok=Arrays.asList(values.split("\\,")).contains(row);
      result(ok?1:0);
    }
  }
}