Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8386749
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 9, 20262026-06-09T18:01:36+00:00 2026-06-09T18:01:36+00:00

I have a MySQL table called category that holds hierarchical data as an adjacent

  • 0

I have a MySQL table called category that holds hierarchical data as an adjacent list. I then echo out the list of all categories and their children as a html list:

Food 
    Fruit  
        Red  
           Cherry  
        Yellow  
           Banana  
    Meat  
        Beef  
        Pork
Sports
    Soccer
        Spanish Soccer
        French Soccer
    Golf
        US Open
           Tiger Woods

The code i am using for that is:

$refs = array();
$list = array();

$sql = "SELECT catid, parentid, name FROM category ORDER BY name";
$result = mysql_query($sql);
while($data = mysql_fetch_assoc($result)) {
    $thisref = &$refs[ $data['catid'] ];

    $thisref['parentid'] = $data['parentid'];
    $thisref['name'] = $data['name'];
    $thisref['catid'] = $data['catid'];    

    if ($data['parentid'] == 0) {
        $list[ $data['catid'] ] = &$thisref;
    } else {
        $refs[ $data['parentid'] ]['children'][ $data['catid'] ] = &$thisref;
    }
}

function toUL($arr){
    $html = '<ul>';
    foreach ($arr as $v){
        $html .= '<li><a href="category.php?id=' . $v['catid'] . '">' . $v['name'] . '</a>';
        if (array_key_exists('children', $v)){
            $html .= toUL($v['children']);
        }
        $html .= '</li>';
    }
    $html .= '</ul>';
    return $html;
}

// build the list and output it
echo toUL($list);

The MySQL table “category” has rows called: catid, name, description, parentid, and level.

The issue is that I want that table to only show the categories that a user likes. Such as:

Food 
    Fruit             
        Yellow  
           Banana  
    Meat  
        Beef    
Sports
    Soccer
        Spanish Soccer
        French Soccer
    Tiger Woods

The "likes" has rows called: likeid, userid, catid where the userid references the primary key of the "users" table and the userid references the primary key of the "category" table.

What sort of code could i implement to create an individual list of topics that a user likes? The issue i see, and do not currently have an answer for is: what if a user likes "Tiger Woods" without liking the parent topic of "Golf"?

How could I output a list of just the categories a user may like?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-09T18:01:37+00:00Added an answer on June 9, 2026 at 6:01 pm

    First you need to join all matching likes of a user together with its category, then select catid, parentid and name of the category part of the join.

    $userid = 123; 
    $sql = "SELECT c.catid, c.parentid, c.name
            FROM category c JOIN likes l ON c.catid=l.catid
            WHERE l.userid=$userid ORDER BY name";
    

    Note that you need to use define which “catid” you want to select out of it, else mysql will give you an error message (It cant decide between catid from the category or likes table of the join; we know it’s not relevant, because it has the same value, but mysql doesn’t ‘realize’ that). I gave category the alias “c” and likes the alias “l”, so you can write c.catid instead of category.catid.

    Regarding the 2nd problem: If the user doesn’t like one of the parent categories. You should display the parent categories even he doesn’t like them, but differently (as different colour). But you at least need all parent nodes, as you need to know where to attach the liked node. Without the intermediate nodes you won’t be able to acomplish that.

    The easiest way is to select an ‘outer’ joined result of the tables ‘categories’ and ‘likes’; ‘outer join’ means that if for one table the other joined information isn’t available (e.g. category row with no like row for that user), then this row of the table (e.g. category) is also added to the result but the part of the unavailable table (here ‘likes’) is set to NULL.

    To be more exakt: we want a “categories LEFT OUTER JOIN likes”, which means: categories (=LEFT) which have or haven’t likes, but no likes that have no category. This should’nt happen. But if, for any reason, you delete a category but don’t delete the likes for it, you’d get into trouble…

    The matching criteria is the catid column, therefore we write “ON c.catid=l.catid” (or “ON categories.catid = likes.catid”, if you don’t want to use the name aliases… as explained below).

    Let’s have a look at the result of the JOIN for this SQL command:

    $userid = 123;
    
    $sql = "SELECT * FROM category c RIGHT OUTER JOIN likes l ON c.catid=l.catid
    WHERE l.userid=$userid ORDER BY l.name";
    

    Now we get a table of all categories with added matching columns from the “like” table, if available… or set to NULL, if unavailable:

    c.catid c.parentid c.name l.catid l.userid
    1       0          Food   1       123
    2       1          Fruits 2       123
    ...
    9       0          Sports NULL    NULL
    10      0          Sports 10      123
    ...
    

    So, what we need is c.catid AS catid, c.parentid AS parentid, c.name AS name (note that we can rename the column names with “AS newname”, so we don’t need to change our program).
    Additionally we need “(l.catid IS NOT NULL) AS liked”, which gives us “true” (value: “1”) for all l.catid with != NULL and “false” (value: “0”) if l.catid == NULL.

    In our SQL command that looks like this:

    $userid = 123; 
    $sql = "SELECT
              c.catid AS catid,
              c.parentid AS parentid,
              c.name AS name,
              (l.catid IS NOT NULL) as liked
            FROM category c RIGHT OUTER JOIN likes l ON c.catid=l.catid WHERE l.userid=$userid
            ORDER BY name";
    

    Ok, now we implement the SQL-result-fetching as before. But a bit modified because of the new “liked” field in the result. And we mark add a “mark”-value to each node, which is initially set for each “liked” node. Later we will also mark all parents of “mark”ed nodes. These are the nodes we want to display…

    $refs = array();
    $list = array();
    
    $userid = 1;
    $sql = "SELECT c.catid, c.parentid, c.name, (l.catid IS NOT NULL) as liked FROM category c RIGHT OUTER JOIN likes l ON c.catid=l.catid WHERE l.userid=$userid ORDER BY name";
    $result = mysql_query($sql);
    while($data = mysql_fetch_assoc($result)) {
        $thisref = &$refs[ $data['catid'] ];
    
        $thisref['parentid'] = $data['parentid'];
        $thisref['name'] = $data['name'];
        $thisref['catid'] = $data['catid'];
        $thisref['liked'] = $data['liked']; // save information: user likes it
        $thisref['mark'] = $data['liked']; // initially mark all 'liked' nodes
    
        if ($data['parentid'] == 0) {
            $list[ $data['catid'] ] = &$thisref;
        } else {
            $refs[ $data['parentid'] ]['children'][ $data['catid'] ] = &$thisref;
        }
    }
    mysql_free_result($result);
    

    Now you recursively mark the part of the tree, that needs to be displayed. Therefore we start at the root of the graph, as for the toUL() function.
    As we want to display any node that has child nodes, that need to be displayed (=is liked by user), we analyze the childs subtree first. If at the end, one of the subtrees has nodes that we need to display OR that node itself needs to be displayed (is liked), we mark it. It’s not much differently from how toUL() works… but the traversal order is different (“childs first, then current node” vs “current node, then childs”). Here’s the code:

    function markLikedSubtree($arr){
      $needs_display = false;
    
      foreach ($arr as $v){
        // recursively mark subtree of child $v
        $child_marked = markLikeSubtree( $v['children'] );
    
        // if mark this node, if it was marked already OR any child of $v needs displaying
        $v['mark'] = $v['mark'] || $child_marked;
    
        // if $v needs to be displayed, the parent needs to be displayed too
        if ($v['mark']) $needs_display = true;
      }
    
      // return true, if parent is needed to be displayed.
      return $needs_display;
    }
    

    Now we need to modify the toUL()-function to only display nodes that have $v[“mark”] == true like this:

    function toUL($arr){
      $html = '<ul>';
      foreach ($arr as $v) {
        if ($v['mark']) {
          $html .= '<li><a href="category.php?id=' . $v['catid'] . '">' . $v['name'] . '</a>';
          if (array_key_exists('children', $v)){
              $html .= toUL($v['children']);
          }
          $html .= '</li>';
        }
      }
      $html .= '</ul>';
      return $html;
    }
    

    And finally we call the function that marks all parent nodes of liked nodes and call our new toUL()-function:

    markLikedSubtree($list);
    echo toUL($list);
    

    Additionally, you can gray out all nodes (=display them differently) that have $v[‘mark’] set but not $v[‘like’]… Or you just add some “is-liked” symbol behind the categories name, if it is liked.
    This could be like this:

    function toUL($arr){
      $html = '<ul>';
      foreach ($arr as $v) {
        if ($v['mark']) {
          $html .= '<li><a href="category.php?id=' . $v['catid'] . '">' . $v['name'] . '</a>';
    
          if ($v['liked']) $html .= " <img src='thumb_up.jpg'>";
    
          if (array_key_exists('children', $v)){
              $html .= toUL($v['children']);
          }
          $html .= '</li>';
        }
      }
      $html .= '</ul>';
      return $html;
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a MySQL database table called Participant that looks something like this: (idParticipant)
I have a very basic mysql table called memberships, that tracks which people belong
Suppose I have a MySQL table called MyTable, that looks like this: +----+------+-------+ |
I have the following mysql table called test. lets say it has the data
I have a php variable: $foo My MySQL table called data has the following
I have a MySQL table called employees . There's another table called shifts that
I have a MySQL table called Hotel . in that i have the following
I have a MySQL table called items that contains thousands of records. Each record
I have a simple table called that contains share prices in MySQL: Table `share_prices`
I have this data on a table called messages (id, category, user) : 1

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.