我试图了解mysql查询如何使用和不使用GROUP BY。
想象一下,我有一个FILM_ACTORS表,其中每个ACTOR_ID都有一个相应的FILM_ID。所以同一个演员参加了N部不同的电影。
我想选择参与20部电影的演员:
SELECT actor_id FROM film_actor GROUP BY actor_id HAVING COUNT(film_id) = 20;
此查询有效,并返回参与20部电影的actor_ids。 但是,如果我刚刚做了什么:
SELECT actor_id FROM film_actor HAVING COUNT(film_id) = 20;
为什么此查询仅返回值,如果我将其等于film_actor表(5463)的SIZE:
SELECT actor_id FROM film_actor HAVING COUNT(film_id) = 5463;
在这种情况下,它会返回actor_id = 1.为什么?是在不考虑相应的actor_ids的情况下选择film_ids吗?
答案 0 :(得分:5)
GROUP BY将结果按以下列的值分组,通常与聚合函数一起使用(例如,COUNT)。
因此,您的第一个查询会为actor_id的每个值返回一行,而HAVING会将结果限制为计数为20的那些
如果没有GROUP BY子句,聚合函数将作用于所有行。因此,您的第二个查询是选择电影数量为20的actor_id,但如果没有分组,则计数为5463(即表格中的行数)。在这种情况下返回的actor_id未确定(即,可能是其中任何一个)。
答案 1 :(得分:4)
第二个查询中没有GROUP BY
。在COUNT
子句中使用聚合函数HAVING
意味着查询最多将返回一行。
与此查询比较:
SELECT actor_id, COUNT(film_id) FROM film_actor
返回单个行,例如
actor_id COUNT(film_id)
-------- --------------
42 5463
(注意:默认情况下,MySQL将返回该查询的结果。其他数据库将拒绝该查询,并在"类型错误中引发"非聚合不在组中。问题在于引用到actor_id
列表中的SELECT
。要使该查询在其他数据库中工作,我们需要从SELECT列表中删除actor_id
。我们可以让MySQL的行为方式相同,如果我们将sql_mode
设置为包含ONLY_FULL_GROUP_BY
。)
请注意,actor_id
返回的值是来自"某行"的值。它不是确定性返回该值的哪一行,它可以来自任何行。 COUNT
返回的值来自整个表格。
如果你想为每个演员提供COUNT
,你需要一个GROUP BY
子句,就像你的第一个查询一样。
SELECT actor_id, COUNT(film_id) FROM film_actor GROUP BY actor_id
从该查询开始,您可以添加HAVING
子句。您还可以从COUNT(film_id)
列表中删除SELECT
。但是,您无法移除GROUP BY
,而不会影响COUNT(film_id)
返回的内容。
答案 2 :(得分:3)
所以,假设你有:
+---------------------------------+
| actor_id | actor_name | film_id |
+---------------------------------+
| 4 | John | 3 |
| 4 | John | 4 |
| 5 | Alex | 3 |
+---------------------------------+
当你跑步时:
SELECT actor_id, COUNT(film_id) AS Films FROM film_actor GROUP BY actor_id;
我们会得到:
+------------------+
| actor_id | Films |
+------------------+
| 4 | 2 |
| 5 | 1 |
+------------------+
所以,我们可以这样做:
SELECT actor_id, COUNT(film_id) AS Films FROM film_actor GROUP BY actor_id WHERE Films = 2;
这应该只返回4的actor_id。