MySQL SELECT语句只返回一行

时间:2014-06-09 16:13:02

标签: php mysql sql pdo

自从我上次提出一个问题以来已经有很长一段时间了,但是为了构建我自己的论坛系统,我一直在乱用SQL。

我的问题的背景是我试图创建一个函数来显示最流行的线程,具体取决于它有多少回复以及最新回复的最近时间。

通过一些阅读,我做了这个SQL语句。

SELECT 
topics.id, 
topics.authorID,
topics.lastReply
FROM 
ms_topics as topics
INNER JOIN
(SELECT inTopic FROM ms_posts) as rcount
ON
rcount.inTopic = topics.id
ORDER BY
topics.lastReply DESC,
count(rcount.inTopic)

然后我使用PDO的fetchAll()函数将结果转换为变量。

$GetPopular = $db->prepare('SQL Statement Above');
$GetPopular->execute();
$Populars = $GetPopular->fetchAll();

而且,为了解决问题,我在var_dump()上使用$populars,它只返回数据库中的一行。

array(1) { [0]=> array(3) { ["id"]=> string(1) "4" ["authorID"]=> string(1) "1" ["lastReply"]=> string(19) "2014-06-08 19:49:50" } }

我的问题基本上是这样的;为什么它不会返回多行,我该怎么做呢?

1 个答案:

答案 0 :(得分:3)

您使用已加入的子查询处于正确的轨道上,但您需要在子查询中应用COUNT() 。否则,聚合组将应用于外部查询,从而生成一行。

这是因为你没有GROUP BY,MySQL很宽松。它为您提供了一行,而不是您期望的结果,其中大多数其他RDBMS会给您一个解析错误。否则,没有COUNT(),MIN(),MAX(),SUM()的聚合函数(GROUP BY等)将永远不会返回多行。

SELECT 
  topics.id, 
  topics.authorID,
  topics.lastReply,
  postsInTopic
FROM 
  ms_topics as topics
  /* The subquery provides the aggregate count
     grouped per inTopic */
  INNER JOIN (
    SELECT
     inTopic,
     COUNT(*) AS postsInTopic
   FROM ms_posts
   GROUP BY inTopic
  ) as rcount ON rcount.inTopic = topics.id
ORDER BY
  topics.lastReply DESC,
  /* Use the alias from the subquery postsInTopic to srot */
  postsInTopic

关于PDO和prepare()的快速说明:虽然它在您的工作流程中是一件好事,但如果您的查询包含prepare()/execute(),则不一定非常必要没有输入值(例如,没有动态WHERE子句)。对于这种情况下的静态查询,您可以安全地调用PDO::query(),而且开销更少,代码更少。