【问题标题】:Count total posts belonging to main category and subcategories in PHP MySQL计算属于 PHP MySQL 中主要类别和子类别的帖子总数
【发布时间】:2016-05-14 10:40:50
【问题描述】:

我需要在 PHP/MySQL 中计算属于一个主要类别及其子类别的帖子总数。我有三个表格:

tb_categories

tb_posts

tb_posts_to_categories

现在要获取属于某个类别及其所有子类别的帖子总数,我使用以下代码:

<?php
include("includes/db-config.php");

// Create connection
$connection = @mysqli_connect(DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME) 
or die(mysqli_connect_error());

    // Get total number of posts in a category
    function get_post_counts($category_id)
    {
        global $connection;
        $category_to_post = array();

        // Build database query
        $sql = "SELECT COUNT(`post_id`) AS `post_count`, `category_id` FROM `tb_posts_to_categories`  GROUP BY `category_id`";

        // Execute database query
        $rs = mysqli_query($connection, $sql);
        while($row = mysqli_fetch_assoc($rs))
        {
            $category_to_post[$row['category_id']] = $row['post_count']; 
        }

        // Build database query
        $sql2 = "SELECT `category_id`, `category_parent` FROM `tb_categories` WHERE `category_parent` <> 0";

        // Execute database query
        $rs2 = mysqli_query($connection, $sql2);

        while($row2 = mysqli_fetch_assoc($rs2))
        {
            $category_to_post[$row2['category_parent']] += $category_to_post[$row2['category_id']]; 
        }

        return $category_to_post[$category_id];
    }

$total_posts = get_post_counts(2);

echo $total_posts;

?>

输出

11

但是这个输出不正确。它应该等于 8。但是如果您提供子类别 id,那么输出是正确的。只有在向函数提供父类别 ID 时才会出现问题。

因为我有一对多的关系。一个帖子可以分配到多个类别,甚至可以分配到它的子类别。再次计算与两个以上类别(一个主要类别及其子类别)相关的帖子,结果是 11 而不是 8。

但是,当帖子与两个不同的父类别或其任何子类别相关联时,代码可以正常工作。仅当帖子与主要类别及其多个子类别相关联时才会出现问题。我们如何解决这种错误的计算?请帮我解决这个问题。谢谢!

【问题讨论】:

  • 在您的主查询中尝试使用SELECT COUNT(distinct post_id) AS post_count
  • 它没有用。我们的主查询中必须需要category_id。单独使用 `COUNT(DISTINCT `post_id`)` 是行不通的。然后我们得到错误。并且将它与category_id 一起使用没有任何效果。结果相同。

标签: php mysql


【解决方案1】:

试试这个来计算类别和它的直接子类别中的帖子。

SELECT COUNT(DISTINCT post_id)
FROM (
  (SELECT post_id
  FROM tb_posts_to_categories
  WHERE category_id = 2)
  UNION ALL
  (SELECT pc.post_id
  FROM tb_posts_to_categories pc
    JOIN tb_categories c ON pc.category_id = c.category_id
  WHERE c.category_parent = 2)
) AS t

这是另一个较小的变体 :-) 但是如果WHERE 包含OR 条件,MySQL 有时会遇到索引使用问题。

SELECT COUNT(DISTINCT pc.post_id)
FROM tb_posts_to_categories pc
  JOIN tb_categories c ON pc.category_id = c.category_id
WHERE c.category_parent = 2 OR c.category_id = 2

【讨论】:

  • 好吧,虽然它有效,但似乎有点复杂和冗长。我们没有其他更简单的解决方案吗?
  • 好的,我添加了更小的例子。
  • 哇!这就像一个魅力。你拯救了我的一天。向你致敬@Andrew。谢谢。
  • 请记住,此示例仅适用于 direct 子类别。不计算二级子类别。
  • 您的问题不包含有关递归计算所有子类别的信息。您的示例受一级限制,答案包含注释:“类别及其直接子类别”。我认为,对于这种情况,这是正确的答案。如果要递归获取所有可能的子类别,则需要动态 sql。例如,内部存储过程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 2019-01-17
  • 1970-01-01
  • 2010-11-22
  • 2011-06-05
  • 1970-01-01
相关资源
最近更新 更多