Какова эквивалентная функция в sqlite для find_in_set (значение, набор) в MySQL? - PullRequest
1 голос
/ 28 октября 2011

Пример ниже 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 ]

5 голосов
/ 28 октября 2011

Моя первая идея заключается в том, что вы не должны хранить данные 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 и присоединяться к другим таблицам для остальных.

0 голосов
/ 29 декабря 2014

Создать функцию

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);
    }
  }
}
0 голосов
/ 20 июня 2014

Я предпочитаю придерживаться тактики, упомянутой Джоном Уэлдоном,

Итак,

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

Ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...