php - MySQL:选择类别、子类别和品牌。只有当它们存在时

标签 php mysql join

我有三个表:

brands(id, name)
categories(id, name)
subcategories(id, category_id, name)

加一个产品表

products(id, category_id, subcategory_id, brand_id, [...])

我需要构建一个三级菜单,如果不多次查询数据库,我很难做到这一点。 基本上菜单是这样的

Electronics -> Smartphones -> Samsung

我的困难是创建一棵像上面那样的树。我不能有例如 Electronics -> Smartphones -> Nike(我有 Nike 作为品牌,但在这个类别/子类别组合中显然不需要 Nike)

到目前为止,我最终在循环中循环以仅获取每个组合存在的品牌,但这会大大增加加载时间。

有没有更有效的方法?

最后我想有类似下面的东西

Electronics
   Smartphones
      Samsung
      Apple
   TVs
      Samsung
      Lg
Shoes
   Sneakers
      Nike
      Converse
...

最佳答案

根据产品表选择(没有空类别/子类别或品牌)
按品牌和子类别分组(无需多行具有相同的“组合”,因为我们不需要在此处显示产品信息)
按字母顺序排列(这里随便做)

$sql = 'SELECT b.id AS brand_id, b.name AS brand_name, sc.id AS subcategory_id, sc.name AS subcategory_name, c.id AS category_id, c.name AS category_name
FROM products p
INNER JOIN brand b ON p.brand_id = b.id
INNER JOIN subcategory sc ON p.subcategory_id = sc.id
INNER JOIN category c ON sc.category_id = c.id
GROUP BY p.brand_id, p.subcategory_id
ORDER BY c.name ASC, sc.name ASC, b.name ASC';

然后在 PHP 中:

$lastCategoryId = 0;
$lastSubCategoryId = 0;

// Fetch results
while($result = // Fetch row) {
    if ($result->category_id != $lastCategoryId) {
    // This is the first time you see that category: display its name (and create a ul tag for example)
        echo '<br />'.$result->category_name.'<br />';
        $lastCategoryId = $result->category_id;
    }
    if ($result->subcategory_id != $lastSubCategoryId) {
    // This is the first time you see that subcategory: display its name (and create a sub-ul tag for example)
        echo '---'.$result->subcategory_name.'<br />';
        $lastSubCategoryId = $result->subcategory_id;
    }

    // No need to check the last brand_id because in the SQL we can't have the same subcategory/brand twice, so it will always be a new brand for this subcategory.
    echo '------'.$result->brand_name.'<br />';
}

*编辑:使用嵌套的 ul/li(未测试)

$lastCategoryId = 0;
$lastSubCategoryId = 0;

// Main list
echo '<ul>';

while($result = // Fetch row) {

    // Category level
    if ($result->category_id != $lastCategoryId) {
    // First time you see that category
        // Re-init subcategory last id (so that later we can know if it's the first subcategory in this category or not)
        $lastSubCategoryId = 0;

        // Close previous category li (if $lastCategoryId == 0, means that there is no category to close, it's our very fist)
        if ($lastCategoryId != 0) {
            echo '</ul></li>';
        }

        // Open li element (which will contain category name + list of subcategories)
        echo '<li>';
        echo $result->category_name;

        // Open sub-ul (which will contain subcategories list)
        echo '<ul>';
    }

    // Subcategory level
    if ($result->subcategory_id != $lastSubCategoryId) {
    // First time you see that subcategory
        // Close previous subcategory li (if $lastSubCategoryId == 0, means that there is no subcategory to close, it's our first one in that category)
        if ($lastSubCategoryId != 0) {
            echo '</ul></li>';
        }

        // Open li element (which will contain subcategory name + list of brands)
        echo '<li>';
        echo $result->subcategory_name;

        // Open sub-sub-ul (which will contain brands list)
        echo '<ul>';
    }

    echo '<li>'.$result->brand_name.'</li>';
}

// Close last subcategory
echo '</ul></li>';

// Close last category
echo '</ul></li>';

// Closing main list
echo '</ul>';

关于php - MySQL:选择类别、子类别和品牌。只有当它们存在时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28725581/

相关文章:

javascript - 使用ajax从数据库加载数据时将复选框添加到数据表

php - Laravel:动态连接数据库

PHP:JSON 或 XML 解析器更快吗?

join - Pig 中多个表的外部连接

mysql - 对按标签过滤的项目进行排序

mysql - 加快 MySQL LEFT JOIN 速度的建议

php - 从 MySQL 查询返回的 PHP 平均时间

mysql - 从日期和时间值位于单独列中的表中选择

mysql - 如何在数据库中存储多个项目。对数据库结构感到困惑

php - 将站点从 Drupal 移动到原始 PHP ...错误 : Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)