select date_format(submit_time,'%Y%m') AS submit_month,
COUNT(*) AS month_q_cnt,
ROUND(COUNT(*) / DAY(LAST_DAY(MIN(submit_time))),3) AS avg_day_q_cnt
FROM practice_record
WHERE YEAR(submit_time) = '2021'
GROUP BY date_format(submit_time,'%Y%m')

union
select '2021汇总' AS submit_month,
COUNT(*) AS month_q_cnt,
ROUND(COUNT(*) / 31,3) AS avg_day_q_cnt
FROM practice_record
WHERE YEAR(submit_time) = '2021'

ORDER BY submit_month

GROUP BY 子句中,必须使用计算的列或者原始的表达式,而不是别名。

last_day 返回参数日期的最后一天,再用day获取天数

union拼接两个查询

改成ROUND(COUNT(*)/DAY(LAST_DAY(MIN(submit_time))),3) AS avg_day_q_cnt 就不会报错了;

2、此处之所以用聚合函数MAX()将submit_time包一下(事实上,MIN\AVG\MAX都可以),是因为已经按月份进行分组了[ GROUP BY DATE_FORMAT(submit_time, '%Y%m') ];

3、从一个角度理解,如果SQL语句中使用了GROUP BY 语句,则SELECT中只能使用常量、聚合函数或GROUP BY中用到的字段;

4、从另一个角度理解,例如,将全班50个人按性别分成两组,你可以问这两个组的性别都是什么(SELECT中使用GROUP BY用到的字段),你可以问这两个组中的总人数是多少(SELECT中使用聚合函数),你不能问第一个组的那个女生叫什么(因为GROUP BY后已经由元素的一阶状态上升为组的二阶状态了)

新知识:

WITH ROLLUP 是一个 MySQL 中用于执行聚合查询并生成汇总行的扩展。当你在使用 GROUP BY 子句时,可以使用 WITH ROLLUP 来添加一个额外的行,显示每个分组的总计。

以下是一个简单的示例,说明如何使用 WITH ROLLUP

假设你有一个名为 orders 的表,其中包含订单信息,你想按照订单的日期和产品对订单进行分组,并计算每个组的销售额。你可以这样查询:

SELECT order_date, product_id, SUM(amount) AS total_amount
FROM orders
GROUP BY order_date, product_id WITH ROLLUP;

这个查询将会按照 order_dateproduct_id 分组,并计算每个组的销售额。同时,它还会生成一个额外的汇总行,显示每个日期和产品组合的总销售额。

使用 WITH ROLLUP 可以让你方便地在查询结果中添加汇总信息,以便更好地理解数据的整体情况。