在树中查询 parents
query parents in a tree
我有数据库 table 任务如下。
SELECT _id,name,parentId FROM Task;
_id name parentId
---------- -------------------- ----------
4 Software Development
5 Machine Learning
6 Programing 4
7 Build System 4
8 version control 4
9 Android App Developm 4
10 Udacity Cource 5
11 Mathematics 5
12 skLearn docs 5
13 problem solving 6
14 breakdown 13
15 language 6
16 c 15
17 c++ 15
18 java 15
19 kotlin 15
20 gradle 7
21 bazel 7
22 git 8
23 svn 8
所有任务及其子任务都在一个 table 中,与各自的 parent 任务相关,使用 _id(主键)和 parentId。
例如任务名称 'java' 的 _id = 18 和 parentId = 15 表示 'java' 是 _id = 15 的子任务,即 'language'.
再次 'language' 有 _id = 15 并且 parentId = 6 意味着 'language' 是 _id = 6 的子任务,即 'Programing'。
同样'Programing'是'Software development'的子任务。
而'Software development'是null的子任务。
所以我需要一个查询,它为输入_id = 18(即'java')提供如下输出,即parent,[= parent 个任务中的 46=]...到子任务的顶部。
_id name parentId
4 Software Development null
6 Programing 4
15 language 6
18 java 15
目前我可以在循环中使用 4 个查询来获取此输出。
SELECT _id,name,parentId FROM task WHERE _id = 18
在下一次迭代中,_id 将是来自上述查询
输出的 parentId 的值
这很耗时,所以我们可以有更好的解决方案吗?
要上树需要递归common table expression:
WITH RECURSIVE parents(id, name, parentid, level) AS (
SELECT _id, name, parentid, 1
FROM Task
WHERE _id = 18
UNION ALL
SELECT Task._id, Task.name, Task.parentid, level + 1
FROM Task
JOIN parents ON Task._id = parents.parentid
)
SELECT id, name, parentid
FROM parents
ORDER BY level DESC;
在 Android Lollipop(API 21 级)之前不支持此功能。
我也有这样的业务,我结合sql和java代码解决了这个问题。
就是这样:
public ArrayList<String> getRecursiveReverse(String parentId) throws Exception {
StringBuffer sqlObject = new StringBuffer();
sqlObject.append("SELECT T.TABLE_ID ");
sqlObject.append("FROM TABLE_NAME T ");
sqlObject.append("WHERE 1 = 1 ");
sqlObject.append(" AND T.STATUS = 1 ");
sqlObject.append(" AND T.PARENT_ID = ? ");
Cursor c = null;
String[] params = { parentId };
ArrayList<String> listIdArray = new ArrayList<String>();
if (!StringUtil.isNullOrEmpty(parentId)) {
listIdArray.add(parentId);
}
try {
c = rawQuery(sqlObject.toString(), params);
if (c != null) {
if (c.moveToFirst()) {
do {
String tableId = CursorUtil.getString(c, "TABLE_ID");
ArrayList<String> tempArray = getShopRecursiveReverse(tableId);
listIdArray.addAll(tempArray);
} while (c.moveToNext());
}
}
} finally {
try {
if (c != null) {
c.close();
}
} catch (Exception e) {
MyLog.w(getTAG(), GlobalUtil.getCurrentMethodName(), e);
}
}
return listIdArray;
}
我有数据库 table 任务如下。
SELECT _id,name,parentId FROM Task;
_id name parentId
---------- -------------------- ----------
4 Software Development
5 Machine Learning
6 Programing 4
7 Build System 4
8 version control 4
9 Android App Developm 4
10 Udacity Cource 5
11 Mathematics 5
12 skLearn docs 5
13 problem solving 6
14 breakdown 13
15 language 6
16 c 15
17 c++ 15
18 java 15
19 kotlin 15
20 gradle 7
21 bazel 7
22 git 8
23 svn 8
所有任务及其子任务都在一个 table 中,与各自的 parent 任务相关,使用 _id(主键)和 parentId。
例如任务名称 'java' 的 _id = 18 和 parentId = 15 表示 'java' 是 _id = 15 的子任务,即 'language'.
再次 'language' 有 _id = 15 并且 parentId = 6 意味着 'language' 是 _id = 6 的子任务,即 'Programing'。
同样'Programing'是'Software development'的子任务。
而'Software development'是null的子任务。
所以我需要一个查询,它为输入_id = 18(即'java')提供如下输出,即parent,[= parent 个任务中的 46=]...到子任务的顶部。
_id name parentId 4 Software Development null 6 Programing 4 15 language 6 18 java 15
目前我可以在循环中使用 4 个查询来获取此输出。
SELECT _id,name,parentId FROM task WHERE _id = 18
在下一次迭代中,_id 将是来自上述查询
输出的 parentId 的值这很耗时,所以我们可以有更好的解决方案吗?
要上树需要递归common table expression:
WITH RECURSIVE parents(id, name, parentid, level) AS (
SELECT _id, name, parentid, 1
FROM Task
WHERE _id = 18
UNION ALL
SELECT Task._id, Task.name, Task.parentid, level + 1
FROM Task
JOIN parents ON Task._id = parents.parentid
)
SELECT id, name, parentid
FROM parents
ORDER BY level DESC;
在 Android Lollipop(API 21 级)之前不支持此功能。
我也有这样的业务,我结合sql和java代码解决了这个问题。 就是这样:
public ArrayList<String> getRecursiveReverse(String parentId) throws Exception {
StringBuffer sqlObject = new StringBuffer();
sqlObject.append("SELECT T.TABLE_ID ");
sqlObject.append("FROM TABLE_NAME T ");
sqlObject.append("WHERE 1 = 1 ");
sqlObject.append(" AND T.STATUS = 1 ");
sqlObject.append(" AND T.PARENT_ID = ? ");
Cursor c = null;
String[] params = { parentId };
ArrayList<String> listIdArray = new ArrayList<String>();
if (!StringUtil.isNullOrEmpty(parentId)) {
listIdArray.add(parentId);
}
try {
c = rawQuery(sqlObject.toString(), params);
if (c != null) {
if (c.moveToFirst()) {
do {
String tableId = CursorUtil.getString(c, "TABLE_ID");
ArrayList<String> tempArray = getShopRecursiveReverse(tableId);
listIdArray.addAll(tempArray);
} while (c.moveToNext());
}
}
} finally {
try {
if (c != null) {
c.close();
}
} catch (Exception e) {
MyLog.w(getTAG(), GlobalUtil.getCurrentMethodName(), e);
}
}
return listIdArray;
}