Have the same table structure to represent a folder tree:

CREATE TABLE FOLDERS([ID] INTEGER PRIMARY KEY, [PARENT_ID] INTEGER, [NAME]
TEXT, [LEVEL] INTEGER, [RANK] TEXT)

Data is as follows:

ID PARENT_ID NAME  LEVEL RANK
-------------------------------------------------------------------------------------------
1 0  Main  0 0
2 1  Diabetic audit 1 0000000001-0000000002
3 1  GROUP BY 1 0000000001-0000000003
4 1  xxxxx  1 0000000001-0000000004
8 1  Common  1 0000000001-0000000008
9 3  zzz  2 0000000001-0000000003-0000000009
10 9  yyy  3 0000000001-0000000003-0000000009-0000000010

Now I would like the following output:
In first column the ID of the folder and in the second column the full path
of that folder.

This will give the right ID's and the right folders in the right order by
doesn't give the full path:

select f.id, f.name as name from folders f where f.id in
(with recursive branch(id) as (select id from folders where id = 1
union all
select f.id from folders f inner join branch b on(f.parent_id = b.id))
select id from branch)
order by rank

This will give the right full paths in the right order but doesn't give me
the right folder ID (1 for all rows):

with recursive folderpath(id, parent_id, path, rank) as
(select id, parent_id, name, rank from folders
union all
select f.id, f.parent_id, f.name || '/' || fp.path, fp.rank from folders f
inner join folderpath fp on (f.id = fp.parent_id))
select id, path from folderpath where id = 1 order by rank

How do I get the right folder ID and the full paths?

RBS

On Sun, May 12, 2019 at 1:15 PM Igor Tandetnik <i...@tandetnik.org> wrote:

> On 5/12/2019 6:19 AM, Philip Bennefall wrote:
> > Hi everyone,
> >
> > I have a tree of folders and I want to find the complete path from any
> arbitrary point back to the top level directory. The schema is:
> >
> > CREATE TABLE IF NOT EXISTS folders(
> >      id INTEGER PRIMARY KEY,
> >      parentFolderId INTEGER REFERENCES folders(id) ON DELETE CASCADE ON
> UPDATE CASCADE,
> >      name TEXT NOT NULL);
> >
> > I made the following CTE:
> >
> > WITH RECURSIVE folderTree (id, path)
> > AS(SELECT id, name FROM folders WHERE parentFolderId IS NULL
> > UNION ALL
> > SELECT folders.id, folderTree.path || '/' || folders.name
> > FROM folders, folderTree WHERE folders.parentFolderId = folderTree.id)
> >   SELECT path FROM folderTree WHERE id=?1;
> >
> > This produces the correct result, but I am wondering if there is a more
> efficient way? This query seems to generate the entire tree and then do a
> table scan to find just the one row I am looking for. Can I start from the
> given row and *only* traverse upwards through the levels until I find a
> node with no parent?
>
> Just reverse the conditions. Something like this (not tested):
>
> WITH RECURSIVE folderPath(id, parentId, path)
> AS(SELECT id, parentFolderId, name FROM folders WHERE id=?1)
> UNION ALL
> SELECT f.id, f.parentFolderId, f.name || '/' || fp.path
> FROM folders f join folderPath fp on (f.id = fp.parentId))
> SELECT path FROM folderPath WHERE parentId is null;
>
> --
> Igor Tandetnik
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to