【问题标题】:Why is SELECT COUNT() returning an aggregated number when I'm expecting a count of each row?当我期望每行的计数时,为什么 SELECT COUNT() 返回一个汇总数字?
【发布时间】:2016-06-10 19:10:56
【问题描述】:

所以我正在努力处理这个非常 (very) 的基本 MySQL 查询,它应该检索按加入的 reactions 数量排序的 courrier 记录。

我有这张桌子:

mysql> describe courrier;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| name         | varchar(255) | NO   |     | NULL    |                |
| envoi        | datetime     | NO   |     | NULL    |                |
| intro        | longtext     | NO   |     | NULL    |                |
| courrier     | longtext     | NO   |     | NULL    |                |
| slug         | varchar(255) | NO   |     | NULL    |                |
| categorie_id | int(11)      | YES  | MUL | NULL    |                |
| reponse      | longtext     | YES  |     | NULL    |                |
| recu         | datetime     | YES  |     | NULL    |                |
| published    | tinyint(1)   | NO   |     | NULL    |                |
| image_id     | int(11)      | YES  | UNI | NULL    |                |
| like_count   | int(11)      | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
12 rows in set (0.02 sec)

其中有:

mysql> select count(id) from courrier;
+-----------+
| count(id) |
+-----------+
|        56 |
+-----------+
1 row in set (0.00 sec)

加入:

mysql> describe reaction;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| courrier_id | int(11)      | YES  | MUL | NULL    |                |
| date        | datetime     | NO   |     | NULL    |                |
| ip          | varchar(15)  | NO   |     | NULL    |                |
| reaction    | longtext     | NO   |     | NULL    |                |
| url         | varchar(255) | YES  |     | NULL    |                |
| name        | varchar(255) | NO   |     | NULL    |                |
| status      | int(11)      | NO   |     | NULL    |                |
| email       | varchar(255) | YES  |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
9 rows in set (0.01 sec)

其中有:

mysql> select count(id) from reaction;
+-----------+
| count(id) |
+-----------+
|       236 |
+-----------+
1 row in set (0.00 sec)

开启:ALTER TABLE reaction ADD CONSTRAINT FK_5DA165A18BF41DC7 FOREIGN KEY (courrier_id) REFERENCES courrier (id);

(为了便于阅读,去掉了反引号)

所以当我运行这个查询时:

SELECT c0_.id AS id_0, 
       c0_.name AS name_1, 
       c0_.slug AS slug_2, 
       c0_.envoi AS envoi_3, 
       c0_.intro AS intro_4, 
       c0_.courrier AS courrier_5, 
       c0_.reponse AS reponse_6, 
       c0_.published AS published_7, 
       c0_.like_count AS like_count_8, 
       c0_.recu AS recu_9, 
       COUNT(r1_.id) AS sclr_10, 
       c0_.image_id AS image_id_11, 
       c0_.categorie_id AS categorie_id_12 
  FROM courrier c0_ 
 INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id 
 ORDER BY sclr_10 DESC LIMIT 25

我很自然地希望在 courrier 中的每条记录都提供一行,以及指定加入的 reaction 记录数的附加列。

但我回来了:1 row in set (0.03 sec)。这是插入到courrier 中的第一条记录,附加列填充有数字242

我做错了什么?

【问题讨论】:

  • 使用分组依据,要统计的列
  • 另请注意,即使 MySQL 允许,在分组时使用没有任何聚合函数的列也是非常糟糕的。在许多情况下,它可能会导致随机结果,尽管这个不应该有任何结果。

标签: mysql join count


【解决方案1】:

您应该使用group by 子句,否则count 将聚合整个结果集:

 SELECT     c0_.id AS id_0 /*, ...*/,
            COUNT(r1_.id) AS sclr_10
 FROM       courrier c0_ 
 INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id 
 GROUP BY   c0_.id
 ORDER BY   sclr_10 DESC 
 LIMIT      25

注意:如果您也对 reaction 中没有对应记录的 courier 记录感兴趣(count = 0),则使用LEFT JOIN 而不是INNER JOIN .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 2019-05-19
    相关资源
    最近更新 更多