SanjayK wrote:
This path is a nice idea to keep it simple for what I want to do. But I have
a question:
Suppose the database is like this:
id, parentid, data
1, 0, parent
2, 1, son B
3, 1, son A
4, 1, daughter A
5, 1, daughter B
6, 2, grandchild B
7, 2, grandchild A
Using the path approach, how can I sort this tree such that the structure
remains same (children immediately after parent) but the children are sorted
in their own level. So the result should be:
id, parentid, data
1, 0, parent
4, 1, daughter A
5, 1, daughter B
3, 1, son A
2, 1, son B
7, 2, grandchild A
6, 2, grandchild B
If I sort using the path then the structure is disturbed because the top
level children are then clubbed together (same path) and their own children
are separated by several rows downwards.
The reason I want to preserve the structure is that I am filling a tree
control and preserving the structure makes it simpler to code in a recursive
manner.
Sanjay,
I'm not sure I follow your question. You cant display an arbitrary tree
so that all children are immediately after their parent. The closest you
could come would be a traversal something like this.
P1
C1
GC1
C2
GC2
GC3
C3
P2
C4
C5
GC4
C6
P3
But in this case, the children of P1 do not follow immediately after P1,
the grandchildren get in the way.
If you only want one level, i.e. the children of a node, don't use the
path. Simply select all the nodes with the parent_id equal to the id of
the node in question.
This is what I do when filling a tree control. I only retrieve the
children when the user expands a node in the tree control. This makes
displaying the tree control very fast since you only need to get the
root nodes first. Then you add nodes to the tree control as the user
expands nodes.
To get the display above the user would initially see the three root nodes
P1
P2
P3
After they expand P1 they would see
P1
C1
C2
C3
P2
P3
If they continued to expand all nodes they would get your ordered
display. You will have done six simple queries, one for each expand
click the user has made.
Actually, there is one small complicating factor, and that is that you
must also determine if you should show an expand control for each node
in your tree control. You only show the expand control if the node has
children. So simply check if each node appears in the parent_id column
of the tree table.
select exists (select id where parent_id = :node_id);
This query will work, but it requires a full table scan to check for the
existence of children. The speed of this query can be greatly improved
by adding an index on the parent_id column.
create index tree_parent on tree(parent_id);
Now this query goes directly to the first child node if present. It
still finds all the children, which may be a concern for a tree with a
high fanout. This can be eliminated by changing the query to only check
for the existence of one child.
select exists (select id where parent_id = :node_id limit 1);
If this query returns true, you add an expand control to the item in the
tree control.
I have also used this path method with large static trees, where I
create a temporary table that stores the count of children for each
node. Then I join this table with the tree to check if I should add the
expand control to a tree item.
HTH
Dennis Cote