SQL 标准要求 GROUP BY 子句包含 ALL 那些 NOT 使用 aggregate function 的列(即 min(),max(),avg( ) 等等)。
SQL92 和更早的版本不允许选择列表的查询,
HAVING 条件或 ORDER BY 列表指的是非聚合列
未在 GROUP BY 子句中命名。
https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
然而,MySQL 为 GROUP BY 实现了一个额外的功能,这是非标准的,并且在旧版本的 MySQL 中它默认为非标准方法。 (有一个服务器设置,您可以将其更改为从标准语法转换为非标准语法进行分组。)自 MySQL 5.7.5 起,默认设置更改为 SQL 标准方法。
MySQL 5.7.5 及更高版本实现了功能依赖检测。如果
ONLY_FULL_GROUP_BY SQL 模式已启用(默认情况下),
MySQL 拒绝选择列表、HAVING 条件或
ORDER BY 列表指的是未在其中命名的非聚合列
GROUP BY 子句在功能上也不依赖于它们。
见:ONLY_FULL_GROUP_BY
几乎可以肯定,您的原始查询不起作用的原因是出于上述考虑。许多人会告诉您,使用非标准方法是不好的做法,实际上,如果您进一步研究该主题,您将了解到非标准方法会为所有未包含在 group by 子句中的列返回“不确定的结果”(除了在极少数情况下)。你最好一直使用标准方法。例如
SELECT
c.IndustryType
, o.OrderDate
, AVG(o.Amount) AS "Average Amount"
, MIN(o.Amount) AS "Minimum Amount"
, MAX(o.Amount) AS "Maximum Amount"
FROM customer c
INNER JOIN orders o ON c.custid = o.custid
GROUP BY
c.IndustryType
, o.OrderDate
;
或
SELECT
c.Custid
, c.Cname
, c.City
, c.IndustryType
, o.OrderNo
, o.OrderDate
, o.SalesPersonID
, o.Amount
, AVG(o.Amount) AS "Average Amount"
, MIN(o.Amount) AS "Minimum Amount"
, MAX(o.Amount) AS "Maximum Amount"
FROM customer c
INNER JOIN orders o ON c.custid = o.custid
GROUP BY
c.Custid
, c.Cname
, c.City
, c.IndustryType
, o.OrderNo
, o.OrderDate
, o.SalesPersonID
, o.Amount
;
值得一提的是,您的原始查询似乎需要为 (IndustryType & OrderDate) 的每个唯一组合计算聚合,但要在更多详细信息行上重复这些聚合。有一些“窗口函数”允许发生这种情况,这些函数正在开发中并打算与 MySQL 8.x 一起发布,这些函数已经存在于其他数据库中,例如 DB2、Oracle、SQL Server、Postgre、SQL Lite、MariaDB(以及更多)。
窗口聚合的语法如下所示:
SELECT
c.Custid
, c.Cname
, c.City
, c.IndustryType
, o.OrderNo
, o.OrderDate
, o.SalesPersonID
, o.Amount
, AVG(o.Amount) OVER(PARTITION BY c.IndustryType, o.OrderDate)
AS "Average Amount"
, MIN(o.Amount) OVER(PARTITION BY c.IndustryType, o.OrderDate)
AS "Minimum Amount"
, MAX(o.Amount) OVER(PARTITION BY c.IndustryType, o.OrderDate)
AS "Maximum Amount"
FROM customer c
INNER JOIN orders o ON c.custid = o.custid