Query om categorie en subcategorie gegevens in HTML te krijgen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Brecht S

Brecht S

18/12/2016 01:11:10
Quote Anchor link
Ik heb in mijn database volgende tabellen:

article_category tabel:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
cat_id   category
1        Elektronica
2        Meubelen


article_subcategory tabel:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
id   cat_id   subcategory         aantal
1    1        Keukenelektronica   1
2    1        Computers           5


Nu wil ik een query opbouwen die in mijn HTML tabel de categorieën en subcategorieën gaat weergeven in dit formaat:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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>


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)
PHP script in nieuw venster Selecteer het PHP script
1
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
Gewijzigd op 18/12/2016 15:44:53 door Brecht S
 
PHP hulp

PHP hulp

28/04/2024 03:57:38
 
Thomas van den Heuvel

Thomas van den Heuvel

19/12/2016 14:58:22
Quote Anchor link
Je zou deze onlangs gegeven 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.
Gewijzigd op 19/12/2016 14:59:24 door Thomas van den Heuvel
 
Brecht S

Brecht S

19/12/2016 18:02:51
Quote Anchor link
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?
 
Ward van der Put
Moderator

Ward van der Put

19/12/2016 18:30:28
Quote Anchor link
Thomas geeft wel de juiste richting aan: herzie je datamodel naar één self-referencing tabel, anders moet je straks alles verbouwen. Inclusief de query.
 
Brecht S

Brecht S

19/12/2016 19:00:24
Quote Anchor link
Wat bedoel je met een self-referencing tabel?
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.
 
Ward van der Put
Moderator

Ward van der Put

19/12/2016 19:47:37
Quote Anchor link
Maak daar één tabel van. Elke categorie die aan andere categorie als ouder (parent) heeft, is namelijk per definitie een subcategorie van die hogere categorie.

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
 
Brecht S

Brecht S

20/12/2016 11:29:51
Quote Anchor link
Ik snap je volledig nu. Maar het probleem is dat die 2 tabellen er zijn en ik dat niet meer kan wijzigen. Er hangt hier een volledig admin systeem aan dat jaren geleden al is geschreven. Anders moet ik dat allemaal zitten aanpassen.
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)
PHP script in nieuw venster Selecteer het PHP script
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
<?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
 
Frank Nietbelangrijk

Frank Nietbelangrijk

20/12/2016 13:36:42
Quote Anchor link
1. maak een query waarin je met een join de subcategorieën aan de categorieën hangt en sorteer deze eerst op category en dan op subcategory. Je kunt dat doen op id of alphabetisch op naam.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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

2. je resultaat is iets als:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
1 electronica 2 Magnetrons
1 electronica 1 Televisies
2 Keuken      3 Snijplanken

3. Nu wil je die magnetron en televisies in een sub lijst hebben onder electronica. Je mag hiervoor dit voorbeeld uitbreiden.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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>';
?>
Gewijzigd op 20/12/2016 14:05:43 door Frank Nietbelangrijk
 
Brecht S

Brecht S

20/12/2016 14:14:36
Quote Anchor link
@Frank: ik heb mijn code werkende gekregen op een andere manier. Bekijk je die even en laat mij eens weten of dit ok is of niet. Jouw code zie ik nu pas, maar ziet er precies minder ingewikkeld uit. Ik wil die wel eens uitproberen.
Alle subitems die een leeg aantal hebben verschijnen niet in mijn navigatie.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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
 
Thomas van den Heuvel

Thomas van den Heuvel

20/12/2016 15:45:40
Quote Anchor link
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.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.