Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 表达式不在GROUPBY子句中_Mysql_Sql_Group By_Aggregate - Fatal编程技术网

Mysql 表达式不在GROUPBY子句中

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,

我在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, 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
表,除非您想只计算具有非NULL
name
列的用户的点击次数(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方面有点盲点!这是来自一些非常旧的代码,我不知道是我拼凑的还是有人提供给我的,但它显然非常丑陋和低效。