Matt
06-30-2005, 07:04 PM
I have a table 'categories' that holds the 'categories_id' row and a 'parent_id' for the parent category This is hierachical data with the topmost, or root, category equaling '0.' Recursive database calls simplify the problem, but for a category 5 or 6 levels deep, this is a lot of overhead to simply retrieve the path. I would like to accomplish the task in a single SQL query. Here is what I have so far:
$path = $db->get_row("SELECT t1.categories_id AS lev1,
t2.categories_id as lev2,
t3.categories_id as lev3,
t4.categories_id as lev4,
t5.categories_id as lev5 FROM categories as t1
LEFT JOIN categories as t2 on t2.parent_id=t1.categories_id
LEFT JOIN categories as t3 on t3.parent_id=t2.categories_id
LEFT JOIN categories as t4 on t4.parent_id=t3.categories_id
LEFT JOIN categories as t5 on t5.parent_id=t4.categories_id
WHERE t5.categories_id=$current_level");
This works in the event that the category is 5 levels deep (useful info obtained from http://conf.phpquebec.com/slides/2005/Dealing_with_hierarchical.ppt). Unfortunately, all categories are not going to have the same depth. Running this query with an additional join (which would cover 6 levels) returns nothing if the category is less than 6 levels deep, so I can't simply assume a maximum depth and use the same query for all categories. I'm also not sure how one would efficiently determine the depth of a given category to determine how many joins are needed (not to mention that this would be an additional database call).
Short of reformatting the database (which is not practical in this particular circumstance), does anyone have an idea of how I might solve this particular problem with a maximum of 2 (1 query to determine depth and another to get complete path) and preferably 1 query?
Thanks in advance, Matt
$path = $db->get_row("SELECT t1.categories_id AS lev1,
t2.categories_id as lev2,
t3.categories_id as lev3,
t4.categories_id as lev4,
t5.categories_id as lev5 FROM categories as t1
LEFT JOIN categories as t2 on t2.parent_id=t1.categories_id
LEFT JOIN categories as t3 on t3.parent_id=t2.categories_id
LEFT JOIN categories as t4 on t4.parent_id=t3.categories_id
LEFT JOIN categories as t5 on t5.parent_id=t4.categories_id
WHERE t5.categories_id=$current_level");
This works in the event that the category is 5 levels deep (useful info obtained from http://conf.phpquebec.com/slides/2005/Dealing_with_hierarchical.ppt). Unfortunately, all categories are not going to have the same depth. Running this query with an additional join (which would cover 6 levels) returns nothing if the category is less than 6 levels deep, so I can't simply assume a maximum depth and use the same query for all categories. I'm also not sure how one would efficiently determine the depth of a given category to determine how many joins are needed (not to mention that this would be an additional database call).
Short of reformatting the database (which is not practical in this particular circumstance), does anyone have an idea of how I might solve this particular problem with a maximum of 2 (1 query to determine depth and another to get complete path) and preferably 1 query?
Thanks in advance, Matt