【问题标题】:MySQL: How to return all rows in a table and count the amount of rows with matching ID from another tableMySQL:如何返回一个表中的所有行并计算另一个表中具有匹配 ID 的行数
【发布时间】:2025-12-31 21:50:01
【问题描述】:

我是一名前端开发人员,请为可怕的 PHP 和 SQL 怜悯我的灵魂,我是来学习的!

所以,我有几个表格,我们称它们为“类别”和“帖子”

我的“类别”表有这些字段:

  • 类别ID
  • 类别名称
  • 类别显示名称

我的“帖子”表有以下字段:

  • postID
  • 帖子标题
  • postCategoryID
  • otherNoneImportantFields

我可以非常简单地输出我所有的类别:

$getCategories = mysql_query("SELECT categoryID, name, displayName 
                              FROM jobCategories 
                              ORDER BY categoryID ASC");
$numberOfCategories = mysql_num_rows($getCategories);

然后我可以做一个while循环并输出所有类别:

if ($numberOfCategories > 0) {
    while($row = mysql_fetch_array($getCategories)) {
        $categoryID = $row['categoryID'];
        $name = $row['name'];
        $displayName = $row['displayName'];

        echo "<li>" . $displayName . "</li>";
        // I'm using the other variables to create a link
    }
}

现在,问题是: 我想要一个 while 循环中的变量,它是具有该 categoryID 的所有帖子的计数。我不确定是否可以进行子查询,或者是否必须进行连接才能使该变量输出。

作为第二个问题,有问题的 PHP 是健全的,还是错过了一种更简单/更清洁的方式来做我正在做的事情?

提前致谢:)

【问题讨论】:

  • stop using mysql_* functions。它们不再被维护并且是officially deprecated。改为了解 prepared statements,并考虑使用 PDO,it's not as hard as you think
  • @Jay:虽然不应该使用 mysql_ 函数编写新代码,但您为什么认为 OP 可以选择使用其他东西?为什么使用准备好的语句和 PDO 是唯一的选择?
  • 我不假设任何事情,我要求他们“考虑”使用 PDO @symcbean。 ¯\_(ツ)_/¯ 无论您选择用于数据库操作的新 API 为何,都应使用准备好的语句,因为它们有助于大大减少 risk for SQL Injection.
  • 很抱歉甚至不知道 PDO。我会尽我所能去研究它,看看我是否可以首先重写简单的东西。感谢您的提醒。
  • @JayBlanchard 您会很高兴知道我现在正在使用 PDO - 您的网站对入门很有帮助。现在看不到一个 mysql_* 函数。

标签: php mysql count categories


【解决方案1】:

这将返回您的 jobCategories 表,其中包含一个额外的列 postsCount,该列等于与该行的 categoryID 匹配的帖子数。

SELECT categoryID, categoryName, categoryDisplayName, IFNULL(postsCounts.cnt, 0) AS postsCount
FROM jobCategories
LEFT JOIN (
  SELECT postCategoryID, count(*) as cnt
  FROM posts
  GROUP BY postCategoryID
) postCounts 
ON postCounts.postCategoryID = jobCategories.categoryID

【讨论】:

  • 为什么 OP 应该“试试这个”?请添加对您所做的事情以及为什么这样做的解释,不仅是为了 OP,也是为了 SO 的未来访问者。
  • 只是想让您知道这对我有很大帮助。我设法让计数工作。谢谢:)
【解决方案2】:

我可以非常简单地输出我所有的类别

即使您的数据库中有一百万行?

是的,您可以进行子查询或联接。重要的是不要在循环中生成第二个 SQL 脚本并继续执行它(因为这将非常效率低下)。

子查询:

SELECT categoryID 
,   name
,   displayName
,   (SELECT COUNT(*)
     FROM posts
     WHERE posts.postCategoryID=jobCategories.categoryID
    ) AS countPosts 
FROM jobCategories 
ORDER BY categoryID ASC;

加入:

SELECT categoryID 
,   name
,   displayName
,   SUM(IF(jobCategories.categoryID IS NULL, 0, 1)) AS countPosts
FROM jobCategories 
LEFT JOIN posts
ON posts.postCategoryID=jobCategories.categoryID
GROUP BY categoryID 
,   name
,   displayName
ORDER BY categoryID ASC;

有问题的 PHP 是否正常

除了记录数的问题之外,如果不先运行查询,您将不会知道 $numberOfCategories - 当 if () {....} 对行为完全没有影响时,这是不必要的的脚本。即使有一个 else {} 原因,在循环遍历 之后测试用例可能会更有效率:

 $count=0;
 while($row = mysql_fetch_array($getCategories) && ++$count<100) {
    ...
 }
 if (!$count) {
    print "No data found";
 } 

【讨论】:

  • 非常感谢您。我觉得这应该可行(我正在做更多的概念证明而不是完善的构建)-但是,我收到以下错误:警告:mysql_fetch_array()期望参数1是资源,给定的布尔值...我以前见过这个,我会做一些挖掘,看看能不能找到解决办法。再次感谢。
最近更新 更多