Boomstructuur PHP
Beste php’er,
Ik wil een soort van boom-structuur maken met php en mysql, deze moet er zo uitzien:
Categorie 1
- sub-categorie 1
- sub-categorie 2
- sub-categorie 3
Categorie 2
- sub-categorie 1
- sub-categorie 2
Hier heb ik de volgende tabel voor bedacht:
Maar wat voor query kan ik hier op loslaten om het in 1 keer te doen, en niet in verschillende delen. Dus 1 query en mogelijk meerdere loops.
Alvast bedankt!
Ik wil een soort van boom-structuur maken met php en mysql, deze moet er zo uitzien:
Categorie 1
- sub-categorie 1
- sub-categorie 2
- sub-categorie 3
Categorie 2
- sub-categorie 1
- sub-categorie 2
Hier heb ik de volgende tabel voor bedacht:
Maar wat voor query kan ik hier op loslaten om het in 1 keer te doen, en niet in verschillende delen. Dus 1 query en mogelijk meerdere loops.
Alvast bedankt!
Gewijzigd op 21/10/2010 17:45:34 door Milo S
Gesponsorde koppelingen:
order_id ?
Echter heb ik het misschien verkeerd geformuleerd, wat daar staat is inderdaad een heel boomstructuur wat ik eigenlijk wil opbouwen is een forum index pagina, hier hoef ik dus niet zo diep voor te gaan.
Ook bij jou voorbeeld gebruiken zij meerdere query's en dit wil ik voorkomen.
Ook bij jou voorbeeld gebruiken zij meerdere query's en dit wil ik voorkomen.
Hoi Milo,
In principe kan je door een SELECT statement waarbij je steeds eerst de naam van de parent ophaalt, per subcategorie al een heel eind komen.
SELECT par_cat.naam AS categorie, cat.naam AS subcategorie FROM categorie AS cat LEFT JOIN categorie AS par_cat ON par_cat.id = cat.parent_id WHERE par.parent_id IS NULL ORDER BY par_cat.naam, cat.naam
Een query met deze opbouw geeft Bijvoorbeeld:
Categorie 1 - sub-categorie 1
Categorie 1 - sub-categorie 2
Categorie 1 - sub-categorie 3
Categorie 2 - sub-categorie 1
Categorie 2 - sub-categorie 2
Hier kan je doormiddel van een simpel loopje doorheen lopen.
In principe kan je door een SELECT statement waarbij je steeds eerst de naam van de parent ophaalt, per subcategorie al een heel eind komen.
SELECT par_cat.naam AS categorie, cat.naam AS subcategorie FROM categorie AS cat LEFT JOIN categorie AS par_cat ON par_cat.id = cat.parent_id WHERE par.parent_id IS NULL ORDER BY par_cat.naam, cat.naam
Een query met deze opbouw geeft Bijvoorbeeld:
Categorie 1 - sub-categorie 1
Categorie 1 - sub-categorie 2
Categorie 1 - sub-categorie 3
Categorie 2 - sub-categorie 1
Categorie 2 - sub-categorie 2
Hier kan je doormiddel van een simpel loopje doorheen lopen.
Hee Robert,
Ik heb je query een bestudeerd en een aantal kleine foutjes eruit gehaald, want hij deed het niet meteen, maar nu wel :D.
De Query:
Nu nog even me brein breken over de loop want dat ging ook iets moeilijker dan ik dacht maar goed. Niet meteen voorkauwen jongens das niet leuk! :P. Ik gaat nog even verder zoeken en me wat meer verdiepen in loops.
Mijn loop vooruitgang
Het ziet er naar uit dat ik niet rechtstreeks met een while loop kan werken, ik zal het eerst op de juiste manier in een array moeten gooien. Als het namelijk in de array staat kan ik het daarna met 2 foreach loops doorlopen. Correct me if I'm wrong.
De array opbouw moet als volgt zijn:
Ik heb je query een bestudeerd en een aantal kleine foutjes eruit gehaald, want hij deed het niet meteen, maar nu wel :D.
De Query:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$qry = "SELECT
cat.titel AS categorie,
subCat.titel AS subcategorie
FROM
categorie AS cat
LEFT JOIN
categorie AS subCat
ON
cat.id = subCat.parent_id
WHERE
cat.parent_id = 0
ORDER BY
cat.id ASC,
subCat.titel";
?>
$qry = "SELECT
cat.titel AS categorie,
subCat.titel AS subcategorie
FROM
categorie AS cat
LEFT JOIN
categorie AS subCat
ON
cat.id = subCat.parent_id
WHERE
cat.parent_id = 0
ORDER BY
cat.id ASC,
subCat.titel";
?>
Nu nog even me brein breken over de loop want dat ging ook iets moeilijker dan ik dacht maar goed. Niet meteen voorkauwen jongens das niet leuk! :P. Ik gaat nog even verder zoeken en me wat meer verdiepen in loops.
Mijn loop vooruitgang
Het ziet er naar uit dat ik niet rechtstreeks met een while loop kan werken, ik zal het eerst op de juiste manier in een array moeten gooien. Als het namelijk in de array staat kan ik het daarna met 2 foreach loops doorlopen. Correct me if I'm wrong.
De array opbouw moet als volgt zijn:
Code (php)
Gewijzigd op 22/10/2010 10:15:14 door Milo S
Lijkt me niet zo moeilijk toch?
Het begint pas leuk en moeilijker te worden wanneer je met meerdere niveau's subcategorieën wil werken.
Code (php)
Het begint pas leuk en moeilijker te worden wanneer je met meerdere niveau's subcategorieën wil werken.
Nou, heb ik dit allemaal werkend, alleen heb ik een probleem, ik moet aan iedere sub categorie ook een id meegeven. Anders kan ik niet met me id's werken wat dus wel moet.
Nu kan ik op zich wel redelijk array's maken enzo, maar met de blokhaken snap ik nog niet helemaal.
Nu kan ik op zich wel redelijk array's maken enzo, maar met de blokhaken snap ik nog niet helemaal.
Je kan zoiets maken:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Gewijzigd op 23/10/2010 11:58:38 door Pim -
Ik zou er in dat geval voor kiezen om de 'subcats' key onderdeel te maken van de bijbehorende 'hoofdcat'. Op die manier houd je alle informatie van een hoofdcat bij elkaar.
Ja, kan ook en is idd ook iets netter, omdat de subcats natuurlijk eigenschappen zijn van de hoofdcat zelf.
Hoi Milo,
Het ging toch om een stukje weergave?
Deze loop zal op jou scherm en de query die hiervoor is gebruikt, keurig de structuur opbouwen zoals je hem hebben wou.
Het ging toch om een stukje weergave?
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
<?php
//bij eerste cat, wel variabele gedefinieerd voor "previous cat"
$prev_cat = '';
while($row = mysql_fetch_assoc($result))
{
if($prev_cat != $row['cat'])
{
echo $row['cat'];
}
echo $row['subcat'];
$prev_cat = $row['cat'];
}
?>
//bij eerste cat, wel variabele gedefinieerd voor "previous cat"
$prev_cat = '';
while($row = mysql_fetch_assoc($result))
{
if($prev_cat != $row['cat'])
{
echo $row['cat'];
}
echo $row['subcat'];
$prev_cat = $row['cat'];
}
?>
Deze loop zal op jou scherm en de query die hiervoor is gebruikt, keurig de structuur opbouwen zoals je hem hebben wou.
Misschien dat je hier wat aan hebt: http://crisp.tweakblogs.net/blog/317/formatting-a-multi-level-menu-using-only-one-query.html
Ik heb nu het volgende probleem. Hij selecteert alles en geeft alles weer, maar omdat ik nu verder ga aantal posts enzo ophalen. Ontstaat er een probleem.
Mijn query:
Nu geeft hij bij posts 2 aan terwijl er maar 1 record in me post tabel staat... heel apart. Het lijkt dus wel of hij alles keer 2 doet, ik kan natuurlijk wel gewoon delen door 2, maar dit is natuurlijk niet de bedoeling. Weet iemand wat er fout gaat? Heb de query nu 2 maal opnieuw opgebouwd in de hoop dat het een simpel foutje was maar dit is helaas niet zo...
Mijn query:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
$qry = "SELECT
cat.title AS cat,
subCat.id AS subCatID,
subCat.title AS subCat,
COUNT(t.id) AS topics,
p.user_id AS postUser,
DATE_FORMAT(p.dateTime, '%d %b %Y, %H:%i') AS newPostDateTime,
COUNT(p.id) AS posts
FROM
categorie AS cat
LEFT JOIN
categorie AS subCat
ON
cat.id = subCat.parent_id
LEFT JOIN
topic AS t
ON
subCat.id = t.cat_id
LEFT JOIN
post AS p
ON
subCat.id = p.cat_id
WHERE
cat.parent_id = 0
GROUP BY
subCat.id
ORDER BY
cat.id,
subCat.title";
?>
$qry = "SELECT
cat.title AS cat,
subCat.id AS subCatID,
subCat.title AS subCat,
COUNT(t.id) AS topics,
p.user_id AS postUser,
DATE_FORMAT(p.dateTime, '%d %b %Y, %H:%i') AS newPostDateTime,
COUNT(p.id) AS posts
FROM
categorie AS cat
LEFT JOIN
categorie AS subCat
ON
cat.id = subCat.parent_id
LEFT JOIN
topic AS t
ON
subCat.id = t.cat_id
LEFT JOIN
post AS p
ON
subCat.id = p.cat_id
WHERE
cat.parent_id = 0
GROUP BY
subCat.id
ORDER BY
cat.id,
subCat.title";
?>
Nu geeft hij bij posts 2 aan terwijl er maar 1 record in me post tabel staat... heel apart. Het lijkt dus wel of hij alles keer 2 doet, ik kan natuurlijk wel gewoon delen door 2, maar dit is natuurlijk niet de bedoeling. Weet iemand wat er fout gaat? Heb de query nu 2 maal opnieuw opgebouwd in de hoop dat het een simpel foutje was maar dit is helaas niet zo...
Gewijzigd op 25/10/2010 16:45:32 door Milo S
Voor het gemak maar een afbeelding geupload,denk dat de uitleg daarbij makkelijker is.
http://www.party-vision.nl/QueryFout.png
http://www.party-vision.nl/QueryFout.png
Kan je van alle gevonden rows een print_r geven?
Ben er inmiddels achter dat de fout bij GROUP BY zit, probeer de oplossing te vinden...
Here it is:
Here it is:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Array
(
[0] => Categorie 1
[cat] => Categorie 1
[1] => 3
[subCatID] => 3
[2] => Subcategorie 1
[subCat] => Subcategorie 1
[3] => 6
[topics] => 6
[4] => 1
[postUser] => 1
[5] => 24 Oct 2010, 11:49
[newPostDateTime] => 24 Oct 2010, 11:49
[6] => 6 [posts] => 6
)
1Array
(
[0] => Categorie 1
[cat] => Categorie 1
[1] => 4
[subCatID] => 4
[2] => Subcategorie 2
[subCat] => Subcategorie 2
[3] => 0
[topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
)
1Array
(
[0] => Categorie 1
[cat] => Categorie 1
[1] => 5
[subCatID] => 5
[2] => Subcategorie 3
[subCat] => Subcategorie 3
[3] => 0 [topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
)
1Array
(
[0] => Categorie 2
[cat] => Categorie 2
[1] => 6
[subCatID] => 6
[2] => Subcategorie 1
[subCat] => Subcategorie 1
[3] => 0
[topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
)
1Array
(
[0] => Categorie 2
[cat] => Categorie 2
[1] => 7 [subCatID] => 7
[2] => Subcategorie 2
[subCat] => Subcategorie 2
[3] => 0 [topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
) 1
(
[0] => Categorie 1
[cat] => Categorie 1
[1] => 3
[subCatID] => 3
[2] => Subcategorie 1
[subCat] => Subcategorie 1
[3] => 6
[topics] => 6
[4] => 1
[postUser] => 1
[5] => 24 Oct 2010, 11:49
[newPostDateTime] => 24 Oct 2010, 11:49
[6] => 6 [posts] => 6
)
1Array
(
[0] => Categorie 1
[cat] => Categorie 1
[1] => 4
[subCatID] => 4
[2] => Subcategorie 2
[subCat] => Subcategorie 2
[3] => 0
[topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
)
1Array
(
[0] => Categorie 1
[cat] => Categorie 1
[1] => 5
[subCatID] => 5
[2] => Subcategorie 3
[subCat] => Subcategorie 3
[3] => 0 [topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
)
1Array
(
[0] => Categorie 2
[cat] => Categorie 2
[1] => 6
[subCatID] => 6
[2] => Subcategorie 1
[subCat] => Subcategorie 1
[3] => 0
[topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
)
1Array
(
[0] => Categorie 2
[cat] => Categorie 2
[1] => 7 [subCatID] => 7
[2] => Subcategorie 2
[subCat] => Subcategorie 2
[3] => 0 [topics] => 0
[4] => [postUser] => [5] => [newPostDateTime] => [6] => 0 [posts] => 0
) 1
Gewijzigd op 25/10/2010 19:25:12 door Milo S
Ik denk dat je van de postcount beter een subquery kan maken ipv een join, dat scheelt hoogstwaarschijnlijk ook een hoop in je performance. Werkt dit?
Zoiets?
Waarom heeft post eigenlijk een cat_id kolom?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
$qry = "SELECT
cat.title AS cat,
subCat.id AS subCatID,
subCat.title AS subCat,
COUNT(t.id) AS topics,
lastPost.user_id AS postUser,
lastPost.date AS newPostDateTime,
lastPost.count AS postCount
FROM
categorie AS cat,
(
SELECT
count(id) as count,
user_id,
DATE_FORMAT(dateTime, '%d %b %Y, %H:%i') as date
FROM
post
WHERE
cat_id = subCat.id
ORDER BY
dateTime DESC
LIMIT
1
) as lastPost
LEFT JOIN
categorie AS subCat
ON
cat.id = subCat.parent_id
LEFT JOIN
topic AS t
ON
subCat.id = t.cat_id
WHERE
cat.parent_id = 0
GROUP BY
subCat.id
ORDER BY
cat.id,
subCat.title";
?>
$qry = "SELECT
cat.title AS cat,
subCat.id AS subCatID,
subCat.title AS subCat,
COUNT(t.id) AS topics,
lastPost.user_id AS postUser,
lastPost.date AS newPostDateTime,
lastPost.count AS postCount
FROM
categorie AS cat,
(
SELECT
count(id) as count,
user_id,
DATE_FORMAT(dateTime, '%d %b %Y, %H:%i') as date
FROM
post
WHERE
cat_id = subCat.id
ORDER BY
dateTime DESC
LIMIT
1
) as lastPost
LEFT JOIN
categorie AS subCat
ON
cat.id = subCat.parent_id
LEFT JOIN
topic AS t
ON
subCat.id = t.cat_id
WHERE
cat.parent_id = 0
GROUP BY
subCat.id
ORDER BY
cat.id,
subCat.title";
?>
Zoiets?
Waarom heeft post eigenlijk een cat_id kolom?
Gewijzigd op 25/10/2010 20:18:25 door Pim -
Helaas loopt dan alles in de soep, geeft ie een dikke error dat subCat niet bestaat terwijl die dat wel doet.
Post heeft een cat_id om zo makkelijk de aantal post per categorie te kunnen tellen.
Post heeft een cat_id om zo makkelijk de aantal post per categorie te kunnen tellen.



