我有数据库表任务如下。
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
一个表中的所有任务及其子任务都使用_id(主键)和parentId与各自的父任务相关。
e.g。任务名称' java' _id = 18,parentId = 15表示' java'是_id = 15的子任务,这是'语言'。
再次'语言' _id = 15,parentId = 6表示语言'是_id = 6的子任务,即编程'。
相同'编程'是软件开发的子任务'。
'软件开发'是null的子任务。
所以我需要一个查询,它输出如下所示输入_id = 18(即' java'),它是父项列表,父项任务的父项...子任务的顶部。
_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的值这是耗时的,所以我们可以有更好的解决方案。
答案 0 :(得分:1)
要在树中上升需要递归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)之前不支持此功能。
答案 1 :(得分:0)
我也有这样的业务,我将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;
}