【问题标题】:return average of counts of records after a group by statement在 group by 语句之后返回记录计数的平均值
【发布时间】:2016-02-22 22:14:17
【问题描述】:

我有一堆记录,我想计算特定时间单位(小时、天、周)内的平均计数。因此,一种情况是我想计算给定范围内我每天拥有的平均记录数。更清楚地说,这只是一个数字。

我现在正在做的方式(显然不起作用,因为它没有取平均值)是以下 sqlalchemy 查询:

db.query(MyClass).filter(MyClass.created.between(start_date, end_date)).group_by(func.HOUR(MyClass.created)).count()

这是SHOW CREATE TABLE yt_video的输出:

| yt_video | CREATE TABLE `yt_video` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `version` int(11) DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `published_date` date DEFAULT NULL,
  `yt_data` text,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |

我真正关心的是创建的时间戳,但希望这会有所帮助。

【问题讨论】:

  • 请提供示例数据和表架构。
  • 您可以使用 numpy.average 或者您可以获取结果,将所有值相加并除以值的计数。

标签: python mysql sql sqlalchemy


【解决方案1】:

这里是answer

在您的情况下,使用提供的表定义:

from sqlalchemy import cast, func
from sqlalchemy.types import TIME, DATE
from sqlalchemy.sql import between

time_from = ...  # get filter time maybe using datetime.time()
time_to = ...  # idem
counts = session.query(func.count('*').label('count')).\
    filter(between(cast(MyClass.created, TIME),
           time_from,
           time_to)).\
    group_by(cast(MyClass.created, DATE))

avg = session.query(func.avg(counts.subquery().columns.count)).scalar()

print avg

【讨论】:

    【解决方案2】:

    出于好奇,在 MySQL 8 及更高版本中,您可以使用窗口函数达到相同的效果:

    # limit(1) should work as well instead of distinct, because we know that all rows
    # contain the exact same result.
    db.query(func.avg(func.count()).over()).\
        filter(MyClass.created.between(start_date, end_date)).\
        group_by(func.date(MyClass.created)).\
        distinct().\
        scalar()
    

    这是可行的,因为逻辑上窗口函数是在 GROUP BY 生成组行之后进行评估的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      相关资源
      最近更新 更多