Mysql SQL-按设备类型获取平均计数

Mysql SQL-按设备类型获取平均计数,mysql,sql,Mysql,Sql,我正在尝试获取每个设备每天的平均事件数。我已经让它大部分工作,但不能让小组的设备吐出所有的设备 数据如下所示: user_id device attribution event_date 1 Desktop Organic 2019-09-02 16:21:44 2 Mobile Organic 2019-09-03 16:22:25 3 Desktop Direct 2019-09-04 16:22:27 4 Tab

我正在尝试获取每个设备每天的平均事件数。我已经让它大部分工作,但不能让小组的设备吐出所有的设备

数据如下所示:

 user_id    device  attribution event_date
 1  Desktop Organic         2019-09-02 16:21:44
 2  Mobile  Organic         2019-09-03 16:22:25
 3  Desktop Direct          2019-09-04 16:22:27
 4  Tablet  Organic         2019-09-04 16:22:29
 5  Desktop Email           2019-09-04 16:22:31
 6  Desktop Email           2019-09-04 16:25:59
 7  Desktop Organic         2019-09-05 16:21:44

 SELECT dt.device AS AcquisitionType, AVG(dt.events) AS AverageEvents
 FROM ( SELECT u.device,
     COUNT (u.event_date) AS events
     FROM users AS u
     GROUP BY DATE(event_date)
     ) AS dt
 GROUP BY dt.device
 ; 

没有得到任何错误。一切正常,但我无法按设备对结果进行分组。

您可以一步完成,无需子查询:

SELECT u.device AS AcquisitionType,
       SUM(u.events)  / COUNT(DISTINCT DATE(u.event_date)) AS AverageEvents
FROM users u
GROUP BY u.device; 

我没发现你的问题有什么不对劲, 有一次我在内部查询中添加了GROUP BY u.device、DATEevent\u date,因为我的MySQL只在_full_GROUP BY中运行,但是从@PaulSpiegel的评论来看,似乎是因为你只在日期上分组,而且你的MySQL不是唯一一个按模式完全分组的MySQL,那么MySQL只是抛出了你所有不同的设备信息,以便让查询成功。我假设mysql从概念上重写了您的查询,这样就不用选择device,而是count。。在内部,它更像是选择maxdevice,count

我强烈建议您只激活“完全分组方式”,这将要求您在“分组方式”中使用设备,因为您在“选择”列表中使用了该设备

另一方面,我提供以下优化:

您需要将每个设备组的事件总数*除以设备的不同天数COUNTDISTINCT DATEu.event\设备引发事件的日期。桌面在3天内有5个事件,所以预计约为1.667。另外两个每天一个:

SELECT 
  u.device AS AcquisitionType,
  COUNT(*)/COUNT(DISTINCT DATE(u.event_date)) AS AverageEvents
FROM users u
GROUP BY u.device; 
我制作了这把小提琴来演示:

模式MySQL v5.7

问题1


在子查询中,它应该是按u.device、DATEevent\u date分组的。但是已经有了一个更好的答案。@Spiegel但是MySQL会加上这个,不是吗?它要么添加它,查询成功,因为选择列表引用了它,要么它不添加它,因为它只处于“完全”模式,然后查询得到一个error@CaiusJard不,没有。如果仅使用组的“u FULL”,则会引发错误。在没有OFGB的情况下,它将使用任意设备在每个日期返回一行。这似乎是在OFGB模式下运行的另一个很好的理由!如果只运行“FULL\u GROUP\u BY”,则会对SQL的新用户造成极大的伤害,因为根据ANSI标准,此查询应该会引发错误。谢谢。你能解释一下这一行发生了什么吗,这样我就能理解:COUNT*/COUNTDISTINCT DATEu.event\u date作为设备在桌面上运行的平均事件,COUNT*将是5,希望非常明显,为什么在这一行上,COUNT只会对任何有效的非空数据累加1,对空数据累加0。它不注意数据本身,因此为什么count*、count0、countdate都返回5。COUNT DISTINCT更微妙,它检查数据本身。如果我们使用DATE函数将时间从datetime中去掉,我们会得到桌面上3个不同的日期-9月2日、3日和4日。因此,count distinct返回3,如果没有distinct,它将返回5,这给了我们5除以桌面上每天3或1.667个事件的结果
CREATE TABLE users (
  `user_id` INTEGER,
  `device` VARCHAR(15),
  `sc` VARCHAR(15),
  `event_date` timestamp
);

INSERT INTO users
  (`user_id`, `device`, `sc`, `event_date`)
VALUES
  ('1', 'Desktop','Organic', '2019-09-02 16:21:44'),
  ('2', 'Mobile', 'Organic','2019-09-03 16:22:25'),
  ('3', 'Desktop','Direct', '2019-09-04 16:22:27'),
  ('4', 'Tablet', 'Organic','2019-09-04 16:22:29'),
  ('5', 'Desktop','Email', '2019-09-04 16:22:31'),
  ('6', 'Desktop','Email', '2019-09-04 16:25:59'),
  ('7', 'Desktop','Organic', '2019-09-05 16:21:44');
    SELECT 
      u.device AS AcquisitionType,
      COUNT(*)/COUNT(DISTINCT DATE(u.event_date)) AS AverageEvents
    FROM users u
    GROUP BY u.device;

| AcquisitionType | AverageEvents |
| --------------- | ------------- |
| Desktop         | 1.6667        |
| Mobile          | 1             |
| Tablet          | 1             |