1

我有如下的数据库表任务。

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与各自的父任务相关。

例如,任务名称“java”有 _id = 18 和 parentId = 15 表示“java”是 _id = 15 的子任务,即“语言”。

同样,“语言”的 _id = 15 和 parentId = 6 意味着“语言”是 _id = 6 的子任务,即“编程”。

同样的“编程”是“软件开发”的子任务。

而“软件开发”是 null 的子任务。

所以我需要一个查询,它为输入_id = 18(即'java')提供如下输出,输入_id = 18(即'java')是父任务列表,父任务的父...到子任务的顶部。

_id 名称 parentId
4 软件开发 null
6 编程 4
15 语言 6
18 爪哇 15

目前我可以在一个循环中使用 4 个查询来获取这个输出。

SELECT _id,name,parentId FROM task WHERE _id = 18

在下一次迭代中,_id 将是来自上述查询输出的 parentId 的值

这很耗时,所以我们可以为此找到更好的解决方案。

4

2 回答 2

1

要上树需要递归公用表表达式

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)之前不支持此功能。

于 2017-10-08T13:19:38.763 回答
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;
}
于 2017-10-09T07:59:49.140 回答