[MySQL]Retrieving single path
Stel ik heb dit:
Ik ben in forum 5 en ik wil een lijst van de parents:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
+-----+-----------------+
|Id |Forum |
+-----+-----------------+
|1 |Forum 1 |
|2 |Forum 2 |
|4 |Forum 4 |
|5 |Forum 5 |
+-----+-----------------+
|Id |Forum |
+-----+-----------------+
|1 |Forum 1 |
|2 |Forum 2 |
|4 |Forum 4 |
|5 |Forum 5 |
+-----+-----------------+
Dit dus. Gewoon dat een forum helemaal wordt terug geleid naar een forum van het hoogste nivo (parent = 0). Ik ben dus op zoek hoe ik dit het beste kan doen.
Ik had dit al gevonden (van MySQL docs):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS' AND t4.name = 'FLASH';
+-------------+----------------------+-------------+-------+
| lev1 | lev2 | lev3 | lev4 |
+-------------+----------------------+-------------+-------+
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |
+-------------+----------------------+-------------+-------+
1 row in set (0.01 sec)
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name = 'ELECTRONICS' AND t4.name = 'FLASH';
+-------------+----------------------+-------------+-------+
| lev1 | lev2 | lev3 | lev4 |
+-------------+----------------------+-------------+-------+
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |
+-------------+----------------------+-------------+-------+
1 row in set (0.01 sec)
Maar dat is niet wat ik zoek omdat ik gewoon een nieuwe result set wil hebben voor iedere parent en ik wil dat het dynamisch is, dus niet met lev1, 2, 3, 4, etc..
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT parent.name
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'FLASH'
ORDER BY parent.lft;
+----------------------+
| name |
+----------------------+
| ELECTRONICS |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS |
| FLASH |
+----------------------+
FROM nested_category AS node,
nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'FLASH'
ORDER BY parent.lft;
+----------------------+
| name |
+----------------------+
| ELECTRONICS |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS |
| FLASH |
+----------------------+
Dat is dus zeg maar wat ik zoek, maar ik wil niet met lft en rgt gaan werken. Eigenlijk is die mogenlijkheid er op dit moment helemaal niet van toepassing.
Dus iemand die mij kan helpen is altijd welkom!`
Bump (half uurtje te vroeg :P)
wss... een vergelijking, met <> ? al draai je dan wel een grotere query, ik denk wel dat lefty en righty nodig zijn hiervoor... Mja, wss zit ik ernaast.
Ik denk dat je er sneller uit komt door "gewoon" een PHP while-lusje en een prepared statement telkens opnieuw uit te voeren. Omdat je waarschijnlijk niet zo heel veel niveaus diep zal gaan, lijkt mij dit niet veel langzamer.
Dus het beste is gewoon alle items te selecteren en dan een lijst op te bouwen? Met PHP dus? En eventueel ook serverside caching dan..
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
public function retrievePath($forum) {
$forumsModel = new forumsModel();
$forumsDump = $forumsModel->allForums();
foreach ($forumsDump as $forumData) $forumsData[$forumData['id']] = $forum;
return array_reverse(ForumsController::getParent($forum, $forumsData, array(array('id' => $forum, 'title' => $forumsData[$forum]['title']))));
}
public function getParent($forum, $forumsData, $currentTree) {
$currentTree[] = array('id' => $forumsData[$forum]['parent'], 'title' => $forumsData[$forumsData[$forum]['parent']]['title']);
if ($forumsData[$forum]['parent'] != 0) {
return ForumsController::getParent($forumsData[$forum]['parent'], $forumsData, $currentTree);
} else {
return $currentTree;
}
}
?>
public function retrievePath($forum) {
$forumsModel = new forumsModel();
$forumsDump = $forumsModel->allForums();
foreach ($forumsDump as $forumData) $forumsData[$forumData['id']] = $forum;
return array_reverse(ForumsController::getParent($forum, $forumsData, array(array('id' => $forum, 'title' => $forumsData[$forum]['title']))));
}
public function getParent($forum, $forumsData, $currentTree) {
$currentTree[] = array('id' => $forumsData[$forum]['parent'], 'title' => $forumsData[$forumsData[$forum]['parent']]['title']);
if ($forumsData[$forum]['parent'] != 0) {
return ForumsController::getParent($forumsData[$forum]['parent'], $forumsData, $currentTree);
} else {
return $currentTree;
}
}
?>
Dit laat lokaal Apache crashen :S
Gewijzigd op 01/01/1970 01:00:00 door Onbekend Onbekend
De code is in ieder geval lekker simpel :)
Code (php)
Gewijzigd op 01/01/1970 01:00:00 door Jelmer -