Mysql 表达式不在GROUPBY子句中
我在MySQL(v5.7)中有一个记录用户请求的日志表,从中我提取了活动的细分,显示了每个月的用户数量和总点击率,例如:Mysql 表达式不在GROUPBY子句中,mysql,sql,group-by,aggregate,Mysql,Sql,Group By,Aggregate,我在MySQL(v5.7)中有一个记录用户请求的日志表,从中我提取了活动的细分,显示了每个月的用户数量和总点击率,例如: Date Users Hits September 2018 20 1,839 August 2018 23 2,723 July 2018 21 1,632 June 2018 22 2,981 这是目前使用以下查询实现的: SELECT month(l.time) m,
Date Users Hits
September 2018 20 1,839
August 2018 23 2,723
July 2018 21 1,632
June 2018 22 2,981
这是目前使用以下查询实现的:
SELECT month(l.time) m, year(l.time) y, date_format(l.time, '%M %Y') monthyear,
(select count(distinct userid) from log lm
where month(lm.time) = month(l.time) and year(lm.time) = year(l.time)) users,
count(u.name) hits
FROM log l left join users u on u.id=l.userid
group by date_format(l.time, '%M %Y')
order by l.time desc, l.id desc
此SQL失败,只启用了_full _group _by,这是MySQL中的默认值,因为并非所有表达式都在group by子句中。我发现的解决方案通常涉及使用聚合函数(如MAX())或将所有表达式添加到GROUP BY子句,但“users”子查询使这些方法有问题:我不能使用MAX()方法(无效语法)将其添加到GROUPBY子句会导致查询速度太慢,以至于我还没有看到测试完成
我觉得可能有一种解决方案既优雅又高效,而不必仅禁用“完整的”group“by”,但我对SQL的理解力有限。我不确定您为什么要使用子查询来实现这一点。这不是你想要的吗
SELECT month(l.time) as m, year(l.time) as y, date_format(l.time, '%M %Y') as monthyear,
count(distinct l.userid) as users,
count(u.name) as hits
FROM log l left join
users u
on u.id = l.userid
GROUP BY m, y, monthyear
ORDER BY max(l.time) desc, l.id desc;
下面是一个简化的查询:
SELECT DATE_FORMAT(l.time, '%M %Y') AS monthyear,
COUNT(DISTINCT l.userid) AS users,
COUNT(*) AS hits
FROM log l
GROUP BY monthyear
您不需要选择列表中的单个月份或年份,因为您没有在所需的结果中显示它
您根本不需要加入users
表,除非您想只计算具有非NULLname
列的用户的点击次数(count忽略NULL,我猜您的意思是计算日志中的所有点击次数,这意味着您应该使用count(*)
而不是count(u.name)
我删除了ORDY BY子句,因为它引用了结果中不存在的列。如果您想在一年中订购,您应该考虑按您想要的方式对月份进行格式化:
SELECT DATE_FORMAT(l.time, '%Y-%m') AS monthyear,
COUNT(DISTINCT l.userid) AS users,
COUNT(*) AS hits
FROM log l
GROUP BY monthyear
逐组默认按值对组进行排序。
有点滑稽。据预测,MySQL通过约束实现适当的组将揭示一系列可怕的代码。在这种情况下考虑重写选项,因为子选择语法是对这个问题的一个非常差的方法。谢谢-看不到树的木头!谢谢,我有一个。在SQL方面有点盲点!这是来自一些非常旧的代码,我不知道是我拼凑的还是有人提供给我的,但它显然非常丑陋和低效。