为啥没有聚合函数的选择列需要成为 MySQL 中 Group by 子句的一部分?
Posted
技术标签:
【中文标题】为啥没有聚合函数的选择列需要成为 MySQL 中 Group by 子句的一部分?【英文标题】:Why columns in selection without aggregate function needs to be part of Group by clause in MySQL?为什么没有聚合函数的选择列需要成为 MySQL 中 Group by 子句的一部分? 【发布时间】:2021-01-16 17:13:08 【问题描述】:这里是SQLZOO Join https://sqlzoo.net/wiki/The_JOIN_operation上第11题的表格链接和详细说明。
问题是询问'对于每场涉及'POL'的比赛,显示比赛ID、日期和进球数。'
下面是我的 SQL 代码
SELECT matchid, mdate, COUNT(player)
FROM game JOIN goal ON id = matchid
WHERE (team1 = 'POL' OR team2 = 'POL')
GROUP BY matchid
错误消息是'gisq.game.mdate' isn't in GROUP BY
。结果在我的代码的最后一行我必须做GROUP BY matchid, mdate
。
我现在正在学习 SQL,谁能帮我理解为什么我必须同时按 matchid
和 mdate
而不是其中一个分组?
提前感谢您的热心帮助。
【问题讨论】:
请注意,手册对此进行了深入介绍。 这是一个常见问题解答。请在考虑发布之前阅读您的教科书和/或手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:***.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。反映你的研究。请参阅How to Ask 和投票箭头鼠标悬停文本。 【参考方案1】:当存在 GROUP BY 或存在任何聚合函数时,SELECT 列表表达式引用未分组的列是无效的,除非在聚合函数中(如 sum、max、min 等,它们将为每个组返回单个值),因为否则会为未分组的列返回多个可能的值,并且 select 不会只返回一个任意值。
但是,有多种解决方法。
选项 1. 你自己做的,将另一列添加到 group by as -
SELECT
matchid
, mdate
, COUNT(player)
FROM game
JOIN goal
ON id = matchid
WHERE (team1= 'POL' OR team2= 'POL')
GROUP BY matchid, mdate;
选项 2。此外,在这种情况下,您可以在另一列上添加聚合函数,如下所示(因为字段 mdate 在功能上取决于匹配 id,因此您可以这样做。您可以使用任何聚合函数会选择一个值)
SELECT
matchid
, max(mdate) as mdate
, COUNT(player)
FROM game
JOIN goal
ON id = matchid
WHERE (team1= 'POL' OR team2= 'POL')
GROUP BY matchid;
选项 3。您可以在子查询中计算聚合,然后将其与自身连接以获得您需要显示的其他列,如下所示
select
t1.matchid
, t2.mdate
, t1.count_player
from
(SELECT
matchid
, COUNT(player) as count_player
FROM game
JOIN goal
ON id = matchid
WHERE (team1= 'POL' OR team2= 'POL')
GROUP BY matchid) t1
join game t2 on t1.matchid = t2.id;
选项4.你也可以使用窗口函数并获取不同的元组值
SELECT distinct
matchid
, mdate
, COUNT(player) over(partition by matchid) as
count_player
FROM game
JOIN goal
ON id = matchid
WHERE (team1= 'POL' OR team2= 'POL');
【讨论】:
以上是关于为啥没有聚合函数的选择列需要成为 MySQL 中 Group by 子句的一部分?的主要内容,如果未能解决你的问题,请参考以下文章
选择列表中的列无效,因为该列没有包含在聚合函数或 GROUP BY 子句中
选择列表中的列无效,因为该列没有包含在聚合函数或 GROUP BY 子句中