Java 基于多个标记从SQLite数据库中选择多个数据

Java 基于多个标记从SQLite数据库中选择多个数据,java,sqlite,android-sqlite,Java,Sqlite,Android Sqlite,我有一个SQLite数据库和一些待办事项列表。 每个待办事项列表中都有一列用于标记 下面是我的SQLite数据库的示例布局 假设我想选择包含“我”和“妈妈”(即“买杂货”、“学习”和“度假旅行”)标签的待办事项列表,我该怎么做 我已经考虑过了,但我不认为它有效。 public getToDoLists (String [] tags) { this.db = openHelper.getReadableDatabase(); String query = " SE

我有一个SQLite数据库和一些待办事项列表。 每个待办事项列表中都有一列用于标记

下面是我的SQLite数据库的示例布局

假设我想选择包含“我”和“妈妈”(即“买杂货”、“学习”和“度假旅行”)标签的待办事项列表,我该怎么做

我已经考虑过了,但我不认为它有效。

public   getToDoLists (String [] tags) {
    this.db = openHelper.getReadableDatabase();
    String query = " SELECT * FROM "
            + TABLE_NAME
            + " WHERE "
            + COL2 + " ='" + tags + "'";
    c = db.rawQuery(query, null);  
    .......
    .......
 } 

您可以使用regexp来实现这一点

注意,默认情况下不提供regexp函数:

默认情况下未定义任何regexp()用户函数,因此 REGEXP运算符通常会导致错误消息。如果 在运行时添加名为“regexp”的应用程序定义的SQL函数, 然后,“X REGEXP Y”操作符将作为对 “regexp(Y,X)”

您可以加载带有ICU扩展名的regexp函数:。因此:

选择
“待办事项列表”
从桌子上
其中1==1
和(“标记”regexp.*\bMom\b.*”
或“标记”regexp.*\bMe\b.*)

ICU regexp语法参考:

这不是一个简单的查询。
您正在将搜索的标记作为字符串数组传递。
一个选项是使用
for
循环,该循环将迭代数组的所有标记,并为每个标记运行一个查询,但这对性能不利。

我建议的选项是将用
分隔的所有标记连接在一个字符串中,并将其传递给查询,查询将使用递归CTE拆分它,并运行
SELECT…
语句,其中包含
EXISTS…
以获取匹配行:

public Cursor getToDoLists(String[] tags) {
    String joinedTags = TextUtils.join(",", tags);

    String query =
            "WITH " +
            "  list(tag) AS (SELECT ?), " +
            "  cte(tag, value) AS ( " +
            "    SELECT SUBSTR(tag, 1, INSTR(tag || ',', ',') - 1), " +
            "           SUBSTR(tag, INSTR(tag || ',', ',') + 1) " +
            "    FROM list " +
            "    UNION ALL " +
            "    SELECT SUBSTR(value, 1, INSTR(value || ',', ',') - 1), " +
            "           SUBSTR(value, INSTR(value || ',', ',') + 1) " +
            "    FROM cte " +
            "    WHERE LENGTH(value) > 0 " +
            ") " +
            "SELECT t.* " +
            "FROM " + TABLE_NAME + " t " +
            "WHERE EXISTS ( " +
            "  SELECT 1 FROM cte c " +
            "  WHERE ',' || REPLACE(t.Tags, ', ', ',') || ',' LIKE '%,' || c.tag || ',%' " +
            ")";

    SQLiteDatabase db = this.getReadableDatabase();

    return db.rawQuery(query, new String[] {joinedTags});
}
我在sql语句中使用了
REPLACE(t.Tags,,,,,,)
,因为我看到列
Tags
中标记的分隔符是
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

如果我弄错了,那么用
t.Tags
替换(t.Tags,,,,,)

方法
getToList()
必须放在
SQLiteOpenHelper
类中,您可以从活动类调用它,如:

Cursor c = openHelper.getToDoLists(new String[] {"Me", "Mom"});
它返回一个
光标
,其中的行与您的条件匹配,您可以对其进行迭代。

要使用
TextUtils.join()
您将需要此导入:

import android.text.TextUtils;

请参阅SQLite中这一功能的详细说明。

您好,谢谢。这很有效。如果我想使用SELECT*FROM TABLE_NAME(Tags,'Dad'),我确实需要将这个“替换(t.Tags,',',',',')”更改为这个“t.Tags”;为什么它会给出错误“没有这样的函数包含”@EhsanRosdi,因为SQLite中没有函数包含()。以下是SQLite支持的函数列表:请改用INSTR()。哦,我的错,谢谢:D