【问题标题】:Rolling ratio with SQL query使用 SQL 查询的滚动比率
【发布时间】:2022-08-17 18:51:24
【问题描述】:

我有一个items 表记录带有布尔列isActive 的项目状态,我想监控活动项目的滚动比率。

现在我有一个程序计算滚动比和事件每 15 分钟调用一次。

INSERT INTO rolling (rolling1d, rolling3d, rolling7d, rolling30d)
SELECT
  (SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 1 DAY) AND isActive = 1)/(SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 1 DAY)) AS ActivityRatioRolling1d,
  (SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 3 DAY) AND isActive = 1)/(SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 3 DAY)) AS ActivityRatioRolling3d,
  (SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 7 DAY) AND isActive = 1)/(SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 7 DAY)) AS ActivityRatioRolling7d,
  (SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 30 DAY) AND isActive = 1)/(SELECT count(id) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 30 DAY)) AS ActivityRatioRolling30d;

如您所见,它根据当前时间确定滚动窗口,计算比率,并将它们插入到rolling 表中,我可以看到每个节拍。

虽然这是功能性的,但我觉得它过于复杂,我应该能够创建一个 SQL 查询,该查询将返回类似于 rolling 表的内容的结果:

date rolling1d rolling3d rolling7d rolling30d
2022-08-17 05:00:00 0,0454545 0,0344828 0,0208333 0,0217391
2022-08-17 05:15:00 0,0425532 0,0327869 0,02 0,0211268
2022-08-17 05:30:00 0,0454545 0,0327869 0,02 0,0212766
2022-08-17 05:45:00 0,047619 0,0327869 0,0204082 0,0214286
2022-08-17 06:00:00 0,0487805 0,0338983 0,0208333 0,0215827
2022-08-17 06:12:00 0,0487805 0,0338983 0,0222222 0,0215827

可能吗?这样的查询会是什么样子?

我感谢您的帮助。

    标签: mysql sql database mariadb


    【解决方案1】:

    您可以使用 AVG() 聚合函数来简化代码:

    INSERT INTO rolling (rolling1d, rolling3d, rolling7d, rolling30d)
    SELECT
      (SELECT AVG(isActive) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 1 DAY)),
      (SELECT AVG(isActive) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 3 DAY)),
      (SELECT AVG(isActive) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 7 DAY)),
      (SELECT AVG(isActive) FROM items WHERE date > DATE_SUB(NOW(), INTERVAL 30 DAY));
    

    或者,对表进行一次扫描:

    INSERT INTO rolling (rolling1d, rolling3d, rolling7d, rolling30d)
    SELECT SUM(date > DATE_SUB(NOW(), INTERVAL 1 DAY) AND isActive) / SUM(date > DATE_SUB(NOW(), INTERVAL 1 DAY)),
           SUM(date > DATE_SUB(NOW(), INTERVAL 3 DAY) AND isActive) / SUM(date > DATE_SUB(NOW(), INTERVAL 3 DAY)),
           SUM(date > DATE_SUB(NOW(), INTERVAL 7 DAY) AND isActive) / SUM(date > DATE_SUB(NOW(), INTERVAL 7 DAY)),
           SUM(date > DATE_SUB(NOW(), INTERVAL 30 DAY) AND isActive) / SUM(date > DATE_SUB(NOW(), INTERVAL 30 DAY))   
    FROM items;
    

    如果你在结果中得到nulls 而你想要0s,你也可以使用COALESCE(),比如:

    COALESCE(AVG(isActive), 0)
    

    或者:

    COALESCE(SUM(date > DATE_SUB(NOW(), INTERVAL 1 DAY) AND isActive) / SUM(date > DATE_SUB(NOW(), INTERVAL 1 DAY)), 0)
    

    【讨论】:

      猜你喜欢
      • 2015-01-30
      • 2021-04-13
      • 2021-06-12
      • 1970-01-01
      • 2013-03-27
      • 2017-05-27
      • 2020-10-08
      • 1970-01-01
      • 2018-08-11
      相关资源
      最近更新 更多