2

if my data structure is like this

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

if i can get "childA.name" . how can i know all the parent name till the top level. so it will be like this > parentA/parentAA/parentAAA/childA

what is the best way to do this ?

i'm working with SQLite and JAVA/android .. thanks in adv.

____________ EDIT

Okay guys, thanks for all of u . so i just make it by repeating "select query". BOTTOM-UP this is the method i create

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
  • Pls do not use recursive function its makes your application performance down Commented Jul 8, 2013 at 5:08
  • 1
    SQLite does not support recursive queries directly (no CTE or CONNECT BY) - there will need to be as many selects (as joins or in multiple queries) per level in an approach that uses a parent-child relationship link. Other approaches which do not need recursion to answer this query include materialized paths and nested sets (search terms). Commented Jul 8, 2013 at 5:08
  • 1
    @DixitPatel Recursive functions are often fine (and SQLite has very low latency) - what really kills performance is failing to use indexes over large sets; or failing to use set joins and indexes for such: e.g. if every node was asked about every parent it had and some other SQL information needed to be gathered based on this - that could turn out very icky! But for a single query (at least as presented), not so bad. Commented Jul 8, 2013 at 5:13
  • okay, so if we can not use recursive function in sqlite, what's the alternatives ? Commented Jul 8, 2013 at 5:59

4 Answers 4

9

In this SQLite Release 3.8.3 On 2014-02-03 has been added support for CTEs. Here is documentation WITH clause Example:

WITH RECURSIVE
cnt(x) AS (
 SELECT 1
 UNION ALL
 SELECT x+1 FROM cnt
  LIMIT 1000000
)
SELECT x FROM cnt;
Sign up to request clarification or add additional context in comments.

Comments

2

I have a table called project with a column named rates. The rates column is a string that holds a JSON array. To split this string into rows that I can use in an IN statement to get rows from the related table, I use this for the IN part

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!=""

Comments

1

You can use nested set model. Nested sets have big advantage that they can be implemented in most SQL engines using simple, non-recursive SQL queries.

2 Comments

Interesting that I've never heard of this. A not to anyone looking at this that this model is read-optimized, and requires a near O(N) for writes.
@heneryville: if you use Nested Intervals, insertion performance issue is easily solvable.
0

SQLite doesn't support recursive CTEs (or CTEs at all for that matter),

there is no WITH in SQLite. Since you don't know how deep it goes, you can't use the standard JOIN trick to fake the recursive CTE. You have to do it the hard way and implement the recursion in your client code:

  • Grab the initial row and the sub-part IDs.
  • Grab the rows and sub-part IDs for the sub-parts.
  • Repeat until nothing comes back.

3 Comments

"Repeat until nothing comes back." how can we do that, is it by query ? or programmatically??
@RR12 If you go from the bottom up, you stop when the current entry does not have a parent. If you go from the top down, you stop when the current entry does not have children.
Generally For Recursive Nature you need to go through bottom up.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.