Query om categorie en subcategorie gegevens in HTML te krijgen
article_category tabel:
article_subcategory tabel:
Nu wil ik een query opbouwen die in mijn HTML tabel de categorieën en subcategorieën gaat weergeven in dit formaat:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<li>
<a href="#">
<div class="clearfix"><span class="pull-left">categorie items</span> <span class="pull-right">(totaal aantal items)</span></div>
</a>
<ul class="test">
<li class="current"><a href="#">subcategorie items (aantal)</a></li>
<?php } ?>
</ul>
</li>
<a href="#">
<div class="clearfix"><span class="pull-left">categorie items</span> <span class="pull-right">(totaal aantal items)</span></div>
</a>
<ul class="test">
<li class="current"><a href="#">subcategorie items (aantal)</a></li>
<?php } ?>
</ul>
</li>
Iemand een idee hoe dit op te bouwen?
Het aantal (totaal aantal items) moet de som zijn van alle aantallen onder die subcategorie.
Ik had al een basis query opgebouwd maar dat is dus niet zoals het moet zijn. Geen idee hoe ik mijn subcats onder mijn cats moet krijgen in de HTML tabel en dan ook nog die aantallen...
Met deze query krijg ik telkens de eerste subcategorie maar de rest niet. Voor de hoofdcat lijkt dit wel te werken.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
SELECT
sc.subcategory,
sc.aantal,
ac.category
FROM
article_category ac
JOIN
article_subcategory sc
ON
sc.cat_id = ac.cat_id
GROUP BY
ac.cat_id
sc.subcategory,
sc.aantal,
ac.category
FROM
article_category ac
JOIN
article_subcategory sc
ON
sc.cat_id = ac.cat_id
GROUP BY
ac.cat_id
Gewijzigd op 18/12/2016 15:44:53 door Brecht S
reactie eens kunnen bestuderen ter inspiratie. Daarin staat min of meer een algemeen recept voor het opbouwen van een datastructuur (in dit geval een boomstructuur).
Het komt er op neer dat je het rekenwerk deels verplaatst naar PHP. Tijdens de opbouw van de boom zou je zoals in die reactie staat aangegeven ook dataverrijking kunnen verrichten. In jouw geval zou dat neerkomen op het uitrekenen van categorie-totalen.
Misschien is de daar geschetste oplossing voor dit moment overkill, maar deze is wel generiek. Mochten er dus meer categorieën (of subsubcategorieën et cetera, je weet maar nooit) toegevoegd worden, zal die oplossing blijven werken.
Indien je die werkwijze niet gebruikt valt het nog steeds aan te raden je probleem op te splitsen in deelproblemen. Deze deelproblemen zullen alle naar oplossingen toe moeten werken die ervoor zorgen dat het uiteindelijk uitdraaien van de geneste bulleted list makkelijk is. Hierbij kan een soort van datastructuur (een soort van genest array) nog steeds handig zijn.
Je zou deze onlangs gegeven Het komt er op neer dat je het rekenwerk deels verplaatst naar PHP. Tijdens de opbouw van de boom zou je zoals in die reactie staat aangegeven ook dataverrijking kunnen verrichten. In jouw geval zou dat neerkomen op het uitrekenen van categorie-totalen.
Misschien is de daar geschetste oplossing voor dit moment overkill, maar deze is wel generiek. Mochten er dus meer categorieën (of subsubcategorieën et cetera, je weet maar nooit) toegevoegd worden, zal die oplossing blijven werken.
Indien je die werkwijze niet gebruikt valt het nog steeds aan te raden je probleem op te splitsen in deelproblemen. Deze deelproblemen zullen alle naar oplossingen toe moeten werken die ervoor zorgen dat het uiteindelijk uitdraaien van de geneste bulleted list makkelijk is. Hierbij kan een soort van datastructuur (een soort van genest array) nog steeds handig zijn.
Gewijzigd op 19/12/2016 14:59:24 door Thomas van den Heuvel
Ik heb je post gelezen maar begrijp het niet zo goed. Lijkt enorm ingewikkeld... Volgens ik kan zien zou je array's moeten maken van je resultaten? Wat bedoel je met je probleem op te splitsen in deelproblemen? Moet ik dan 2 query's door elkaar laten draaien, dus 2 while's? Of ben ik totaal niet mee?
Thomas geeft wel de juiste richting aan: herzie je datamodel naar één self-referencing tabel, anders moet je straks alles verbouwen. Inclusief de query.
Momenteel heb ik 2 tabellen zoals aangegeven. Een voor de cats en 1 voor de subcats. Die hangen uiteraard wel aan elkaar. Zie mijn gepost voorbeeld.
De self-referencing table is een gangbaar design pattern voor hiërarchische structuren. Als je de afhankelijke sleutel (foreign key) laat terugverwijzen naar de primaire sleutel (primaire key) van een record in dezelfde tabel, dan weet je: x is een kind van y. En dus bijvoorbeeld: deze categorie x is een subcategorie van categorie y, in dezelfde tabel.
Bedenk maar eens wat er moet gebeuren wanneer je ouders (categorieën) en kinderen (subcategorieën) hebt, maar één van die kinderen een kleinkind krijgt. Het kleinkind is dan géén sub-subcategorie (in een derde tabel), maar gewoon weer opnieuw een kind (subcategorie) van een ouder (categorie). waarbij die ouder toevallig zelf een subcategorie is. Dus: elke subcategorie is een categorie.
Gewijzigd op 19/12/2016 19:49:24 door Ward van der Put
Is er geen oplossing voor mijn 2 tabellen hier? Ik heb geen idee.
Het gaat over 1 hoofdcategorie en 1 subcategorie. Dieper gaan de levels niet gaan.
Toevoeging op 20/12/2016 12:49:07:
Ik heb een deel van de vraag al gevonden. Zie hieronder (PDO of mysqli deel doe ik later als alles werkende is). Ik gebruik hier de group_concat in de mysql:
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
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
<?php
//Database connection komt hier
$sql = "
SELECT
ac.category,
sc.aantal,
sc.subcategory ,
group_concat(sc.subcategory) as items
FROM
article_category ac
JOIN
article_subcategory sc
ON
sc.cat_id = ac.cat_id
GROUP BY
ac.cat_id
";
$res = mysql_query($sql) or die (mysql_error());
while($row = mysql_fetch_assoc($res)) {
?>
<ul>
<li><?php echo $row['category']; ?></li>
<?php
$items = $row['items'];
$items_array = explode(',',$items);
if(is_array($items_array) && count($items_array) > 0 ){
?>
<ul>
<?php foreach($items_array as $item_name){ ?>
<li>
<?php echo $item_name; ?>
</li>
<?php } ?>
</ul>
<?php } ?>
</ul>
<?php } ?>
//Database connection komt hier
$sql = "
SELECT
ac.category,
sc.aantal,
sc.subcategory ,
group_concat(sc.subcategory) as items
FROM
article_category ac
JOIN
article_subcategory sc
ON
sc.cat_id = ac.cat_id
GROUP BY
ac.cat_id
";
$res = mysql_query($sql) or die (mysql_error());
while($row = mysql_fetch_assoc($res)) {
?>
<ul>
<li><?php echo $row['category']; ?></li>
<?php
$items = $row['items'];
$items_array = explode(',',$items);
if(is_array($items_array) && count($items_array) > 0 ){
?>
<ul>
<?php foreach($items_array as $item_name){ ?>
<li>
<?php echo $item_name; ?>
</li>
<?php } ?>
</ul>
<?php } ?>
</ul>
<?php } ?>
Nu zou ik ook de aantal moeten hebben per subcat. Ik denk dat ik die ergens in de $items_array zal moeten opnemen. Alleen zie ik nog niet hoe dat te doen? En dan nog de totalen per category (van alle subitems onder die categorie).
Gewijzigd op 20/12/2016 12:50:15 door Brecht S
Code (php)
1
2
3
4
2
3
4
SELECT c.id, c.name, s.id as sub_id, s.name as sub_name
FROM subcategory s
LEFT JOIN category c ON c.id = s.cat_id
ORDER BY c.name, s.name
FROM subcategory s
LEFT JOIN category c ON c.id = s.cat_id
ORDER BY c.name, s.name
2. je resultaat is iets als:
3. Nu wil je die magnetron en televisies in een sub lijst hebben onder electronica. Je mag hiervoor dit voorbeeld uitbreiden.
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
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
<?php
$cat_id = 0;
$must_close = false;
echo '<ul>';
while($row = mysqli_fetch_assoc($result))
{
// wanneer we aan een andere categorie beginnnen
if($row['id'] != $cat_id)
{
// de eerste keer hoeven we de lists nog niet af te sluiten. Daarna wel.
if($must_close)
echo '</ul></li>';
// onthoud het huidige categorie id zodat we deze bij de volgende kunnen vergelijken om te zien of ie al veranderd is.
$cat_id = $row['id'];
// open de nieuwe categorie listitem
echo '<li>' . $row['name'] . '<ul>';
// openen betekent dat we hem ook moeten sluiten
$must_close = true;
}
// voeg een subcategorie toe aan de lijst
echo '<li>' . $row['sub_name'] . '</li>';
}
// De laatste categorie listitem afsluiten
if($must_close)
echo '</ul></li>';
echo '</ul>';
?>
$cat_id = 0;
$must_close = false;
echo '<ul>';
while($row = mysqli_fetch_assoc($result))
{
// wanneer we aan een andere categorie beginnnen
if($row['id'] != $cat_id)
{
// de eerste keer hoeven we de lists nog niet af te sluiten. Daarna wel.
if($must_close)
echo '</ul></li>';
// onthoud het huidige categorie id zodat we deze bij de volgende kunnen vergelijken om te zien of ie al veranderd is.
$cat_id = $row['id'];
// open de nieuwe categorie listitem
echo '<li>' . $row['name'] . '<ul>';
// openen betekent dat we hem ook moeten sluiten
$must_close = true;
}
// voeg een subcategorie toe aan de lijst
echo '<li>' . $row['sub_name'] . '</li>';
}
// De laatste categorie listitem afsluiten
if($must_close)
echo '</ul></li>';
echo '</ul>';
?>
Gewijzigd op 20/12/2016 14:05:43 door Frank Nietbelangrijk
Alle subitems die een leeg aantal hebben verschijnen niet in mijn navigatie.
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
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
<?php
//Database connection komt hier
$sql = "
SELECT
ac.category,
sc.aantal,
sc.subcategory ,
group_concat(sc.subcategory) as items,
group_concat(sc.aantal) as totals,
SUM(sc.aantal) as mainItemsTotal,
group_concat(CONCAT(sc.subcategory, '-', sc.aantal)) as items2
FROM
article_category ac
JOIN
article_subcategory sc
ON
sc.cat_id = ac.cat_id
GROUP BY
ac.cat_id
ORDER BY
ac.category asc, sc.subcategory asc
";
$res = mysql_query($sql) or die (mysql_error());
while($row = mysql_fetch_assoc($res)) {
?>
<ul>
<li><?php echo $row['category']; ?> (<?php echo $row['mainItemsTotal']; ?>)</li>
<?php
$items = $row['items2'];
$items_array = explode(',',$items);
if(is_array($items_array) && count($items_array) > 0 ){
?>
<ul>
<?php
foreach($items_array as $item_name){
$arr = explode('-',$item_name);
if($arr[1] > 0) { ?>
<li>
<?php echo $arr[0] . ' ('. $arr[1]. ')'; ?>
</li>
<?php
}
}
?>
</ul>
<?php } ?>
</ul>
<?php } ?>
//Database connection komt hier
$sql = "
SELECT
ac.category,
sc.aantal,
sc.subcategory ,
group_concat(sc.subcategory) as items,
group_concat(sc.aantal) as totals,
SUM(sc.aantal) as mainItemsTotal,
group_concat(CONCAT(sc.subcategory, '-', sc.aantal)) as items2
FROM
article_category ac
JOIN
article_subcategory sc
ON
sc.cat_id = ac.cat_id
GROUP BY
ac.cat_id
ORDER BY
ac.category asc, sc.subcategory asc
";
$res = mysql_query($sql) or die (mysql_error());
while($row = mysql_fetch_assoc($res)) {
?>
<ul>
<li><?php echo $row['category']; ?> (<?php echo $row['mainItemsTotal']; ?>)</li>
<?php
$items = $row['items2'];
$items_array = explode(',',$items);
if(is_array($items_array) && count($items_array) > 0 ){
?>
<ul>
<?php
foreach($items_array as $item_name){
$arr = explode('-',$item_name);
if($arr[1] > 0) { ?>
<li>
<?php echo $arr[0] . ' ('. $arr[1]. ')'; ?>
</li>
<?php
}
}
?>
</ul>
<?php } ?>
</ul>
<?php } ?>
Gewijzigd op 20/12/2016 14:16:41 door Brecht S
Quote:
Er hangt hier een volledig admin systeem aan dat jaren geleden al is geschreven.
Dan is dit mogelijk sowieso aan een revisie toe. Ik zie in bovenstaand fragment bijvoorbeeld mysql_-functies?
Quote:
Anders moet ik dat allemaal zitten aanpassen.
Vroeger of later gaat dit waarschijnlijk toch gebeuren. Nu schuif je dit voor je uit. Op een gegeven moment sta je vast door alles wat je voor je uitschuift :p.
Quote:
Het gaat over 1 hoofdcategorie en 1 subcategorie. Dieper gaan de levels niet gaan.
TOTDAT... :D
Wanneer je echter een generieke aanpak gebruikt (zoals die van Ward) loop je nooit tegen dit probleem aan.