2

我有这个查询并导致我的数据库:

mysql> SELECT id FROM jos_content 
       WHERE catid=12 AND state=1 
       AND DATE(publish_up) <= NOW() ORDER BY DATE(publish_up) DESC LIMIT 0,5;
    +----+
    | 编号 |
    +----+
    | 48 |
    | 47 |
    | 46 |
    +----+
    3 行一组(0.00 秒)

现在我想计算结果:

mysql> SELECT count(*), id FROM jos_content 
       WHERE catid=12 AND state=1 
       AND DATE(publish_up) <= NOW() ORDER BY DATE(publish_up) DESC LIMIT 0,5;
    +----------+----+
    | 计数(*) | 编号 |
    +----------+----+
    | 3 | 46 |
    +----------+----+
    一组中的 1 行(0.00 秒)

为什么没有显示 48 和 47 结果?

先感谢您

4

2 回答 2

3

您需要包含一个GROUP BY子句。默认情况下,MySQL 允许SELECT子句中不包含在 a 中的列GROUP BY(这在大多数其他 RDBMS 中是错误的)。如果没有GROUP BY,MySQL 将返回关联列中的第一个,这通常不是正确的预期结果。

SELECT 
  count(*), 
  id
FROM jos_content
WHERE catid=12 AND state=1 AND DATE(publish_up) <= NOW() 
GROUP BY id
ORDER BY DATE(publish_up) DESC
LIMIT 0,5;

如果您想在摘要中返回始终唯一的多个列,则不需要 中的所有列GROUP BY会很有帮助,如下所示,其中 对name是唯一的id,但是您必须对至少一个列进行分组才能使聚合正确运行并生成总结:

SELECT 
  id,
  name,
  COUNT(*)
FROM tbl
GROUP BY id

为了与其他 RDBMS 兼容并避免错误,我建议始终在显式中包含所有SELECTGROUP BY

更新

更好地了解您的尝试后,如果您想要每行 id 旁边的所有行的总数,您可以使用SELECT列表中的子选择。不过这会有点慢。

SELECT
  id,
  (SELECT COUNT(*) FROM jos_content) AS numitems
FROM jos_content
WHERE catid=12 AND state=1 AND DATE(publish_up) <= NOW() 
ORDER BY DATE(publish_up) DESC
LIMIT 0,5;

您可以通过对子查询中的计数进行笛卡尔连接(无子句)来欺骗它以更快地工作ON,因此不应为每一行执行它。仅当子查询将返回恰好一行时才执行此操作。

SELECT
  id
  numitems
FROM 
  jos_content
  /* Join with no ON clause */
  JOIN (SELECT COUNT(*) AS numitems FROM jos_content) subq
WHERE catid=12 AND state=1 AND DATE(publish_up) <= NOW() 
ORDER BY DATE(publish_up) DESC
LIMIT 0,5;
于 2012-05-11T14:02:04.990 回答
0

Count 是聚合函数,因此如果要包含任何列,则该列必须是查询中 group by 子句的一部分。

于 2012-05-11T14:05:03.190 回答