在树中查询 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;
}