如何在SQLite中进行递归查询?

时间:2013-07-08 05:05:43

标签: java android sqlite

如果我的数据结构是这样的

parentA
-------parentAA
--------------parentAAA
---------------------childA

如果我能得到“childA.name”。我怎么能知道所有的父母名字直到最高级别。 所以它会是这样的> parentA/parentAA/parentAAA/childA

这样做的最佳方式是什么?

我正在使用SQLite和JAVA / android ..感谢adv。

__ _ __ _ __ _ ___ 编辑

好的伙计们,谢谢你们所有人。所以我只是通过重复“选择查询”来实现。 BOTTOM-UP这是我创建的方法

public String getPath(int id, int type) {
        StringBuilder pathBuilder = new StringBuilder();
        String sql = null;
        int parentId = 0;

        if (id == 0) {
            pathBuilder.insert(0, "/root/");
            return pathBuilder.toString();
        }

        if (type == LayerManagementActivity.PARENT) {
            do {
                sql = "SELECT id, name, parent_id from parents_table where id="
                        + id;
                Cursor c = mDatabase.rawQuery(sql, null);
                if (c.moveToFirst()) {
                    parentId = c.getInt(2);
                    id = c.getInt(0);
                    pathBuilder.insert(0, "/" + c.getString(1));
                    c.close();
                }
                id = parentId;
            } while (parentId != 0);

            pathBuilder.insert(0, "/root");
            pathBuilder.append("/");

        } else if (type == LayerManagementActivity.CHILD) {
            sql = "SELECT id, name, folder_id FROM childs_table WHERE id=" + id;
            Cursor c = mDatabase.rawQuery(sql, null);
            if (c.moveToFirst()) {
                pathBuilder.append(c.getString(1));
                id = c.getInt(0);
                int folderId = c.getInt(2);
                String path = getPath(folderId, LayerManagementActivity.PARENT);
                pathBuilder.insert(0, path);
            }
            c.close();
        }
        Log.d("crumb", pathBuilder.toString());
        return pathBuilder.toString();
    }

4 个答案:

答案 0 :(得分:9)

在此SQLite Release 3.8.3 On 2014-02-03中增加了对CTE的支持。这是文档WITH clause 例如:

WITH RECURSIVE
cnt(x) AS (
 SELECT 1
 UNION ALL
 SELECT x+1 FROM cnt
  LIMIT 1000000
)
SELECT x FROM cnt;

答案 1 :(得分:2)

我有一个名为project的表,其中包含一个名为rates的列。 rates列是一个包含JSON数组的字符串。 要将此字符串拆分为可在IN语句中使用的行以从相关表中获取行,我将其用于IN部分

WITH
 split(s, p) AS (
 SELECT substr(printf("%s%s", ss, ","), instr(ss, ",")+1), trim(substr(ss, 0, instr(ss, ","))) from ( select replace(replace(rates,"[",""), "]","") ss from project where rowid = 1)
 UNION ALL
 SELECT substr(s, instr(s, ",")+1), trim(substr(s, 0, instr(s, ","))) FROM split
 where p!=""
 )
 select p from split where p!=""

答案 2 :(得分:1)

您可以使用nested set model。嵌套集具有很大的优势,它们可以使用简单的非递归SQL查询在大多数SQL引擎中实现。

答案 3 :(得分:0)

SQLite不支持递归CTE(或根本不支持CTE)

SQLite中没有WITH。由于你不知道它有多深,你不能使用标准的JOIN技巧伪造递归CTE。您必须以艰难的方式完成并在客户端代码中实现递归:

  • 抓取初始行和子部件ID。
  • 抓取子部件的行和子部件ID。
  • 重复直到什么都没有回来。