You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用sqlite3模块计算SQLite中最近N条记录的平均值?

问题

我正在使用Python 3.11,结合tkinter和sqlite3包开发体重追踪程序。已创建包含四列的数据库表weights,其中一列名为weight,数据类型为real(小数/浮点数)。我希望编写一个使用cursor.execute的函数,选取weight列最近7条记录,计算并返回其平均值。

我知道SQLite3内置AVG()函数,但它默认计算全列平均值,不知道如何只计算最近N条;也试过cursor.fetchmany(7)方法,但取出的数据是元组,手动计算平均值时遇到元组无法与数值直接交互的错误。

当前函数代码执行后得到的是全列平均值,而非最近7条的:

def average_query():
    
    #Create a database or connect to one
    conn = sqlite3.connect('weight_tracker.db')
    #Create cursor
    c = conn.cursor()
    
    my_average = c.execute("SELECT round(avg(weight)) FROM weights ORDER BY oid DESC LIMIT 7")
    my_average = c.fetchall()
    my_average = my_average[0][0]
    
    #Create labels on screen
    average_label = Label(root,text=f"Your average 7-day rolling weight is {my_average} pounds.")
    average_label.grid(row=9, column=0, columnspan=2)

    #Commit changes
    conn.commit()
    #Close connection
    conn.close()
解决方案

核心问题是SQL语句的逻辑顺序错误:原语句先对全列计算AVG(weight),再对结果取前7条(但聚合函数返回的只有1条结果,所以LIMIT 7完全不起作用)。正确逻辑是先筛选出最近7条记录,再对这7条计算平均值。

方法1:修正SQL语句(推荐)

调整SQL结构,用子查询先获取最近7条的weight值,再对这些值计算平均值:

def average_query():
    conn = sqlite3.connect('weight_tracker.db')
    c = conn.cursor()
    
    # 先取最近7条记录的weight,再计算平均值并四舍五入
    c.execute("SELECT ROUND(AVG(weight)) FROM (SELECT weight FROM weights ORDER BY oid DESC LIMIT 7)")
    my_average = c.fetchone()[0]  # fetchone比fetchall更高效,直接取唯一结果
    
    average_label = Label(root, text=f"Your average 7-day rolling weight is {my_average} pounds.")
    average_label.grid(row=9, column=0, columnspan=2)

    conn.commit()
    conn.close()
  • 子查询(SELECT weight FROM weights ORDER BY oid DESC LIMIT 7)按oid倒序取出最近7条的weight值
  • 外层查询对这7条数据计算平均值,再用ROUND()处理小数位数
  • 用fetchone()替代fetchall(),直接获取聚合后的唯一结果,代码更简洁

方法2:手动计算平均值(适合需额外处理数据的场景)

如果需要先获取7条数据再手动计算,可通过遍历元组提取数值:

def average_query():
    conn = sqlite3.connect('weight_tracker.db')
    c = conn.cursor()
    
    c.execute("SELECT weight FROM weights ORDER BY oid DESC LIMIT 7")
    recent_weights = c.fetchall()
    
    # 遍历元组提取数值,计算平均值,处理无数据的情况
    total = sum(weight[0] for weight in recent_weights)
    my_average = round(total / len(recent_weights)) if recent_weights else 0
    
    average_label = Label(root, text=f"Your average 7-day rolling weight is {my_average} pounds.")
    average_label.grid(row=9, column=0, columnspan=2)

    conn.commit()
    conn.close()
  • recent_weights是包含7个元组的列表(每个元组为(weight_value,)),通过weight[0]提取浮点数
  • 增加空数据判断,避免除以0的错误

内容的提问来源于stack exchange,提问作者Jay_SK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:25:17