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

如何通过更少SQL查询实现Python对接MySQL的报表统计需求

方案1:MySQL侧一次计算所有统计值(推荐,资源消耗最低)

你所有查询的f_id固定,仅col1-col5为100组可变组合,直接将所有组合拼入单次SQL的筛选条件,用GROUP BY直接返回所有组合的统计值,不需要拉取全量原始数据,IO开销最低。

from collections import defaultdict

# 先把所有需要查询的col1-col5组合整理成列表
query_combs = [
    ('a', 'a', 'a', 'x', 1),
    ('a', 'b', 'a', 'x', 1),
    ('a', 'a', 'b', 'x', 1),
    ('a', 'a', 'a', 'z', 1),
    ('a', 'a', 'a', 'z', 2),
    # 剩下的94组组合补在这里
]
fixed_f_id = 123

# 构造SQL
mycursor = mydb.cursor()
# 每个组合对应一个条件片段
condition_fragment = "(" + " AND ".join([f"col{i}=%s" for i in range(1,6)]) + ")"
all_conditions = " OR ".join([condition_fragment]*len(query_combs))
sql = f"""
SELECT col1, col2, col3, col4, col5, COUNT(*) as cnt
FROM mytable
WHERE f_id = %s AND ({all_conditions})
GROUP BY col1, col2, col3, col4, col5
"""
# 构造参数:第一个是f_id,后面依次展开所有组合的元素
params = [fixed_f_id]
for comb in query_combs:
    params.extend(comb)

mycursor.execute(sql, params)
# 结果转字典,方便后续查询
count_map = defaultdict(int)
for col1, col2, col3, col4, col5, cnt in mycursor.fetchall():
    count_map[(col1, col2, col3, col4, col5)] = cnt

# 使用的时候直接取即可
print(count_map[('a', 'a', 'a', 'x', 1)])
print(count_map[('a', 'b', 'a', 'x', 1)])

方案2:拉取全量数据用Python原生库统计(适合f_id对应数据量较小的场景)

如果f_id过滤后的数据量在10万条以内,直接拉取所有col1-col5记录,用标准库collections.Counter统计即可,无额外依赖,速度极快:

from collections import Counter

fixed_f_id = 123
mycursor = mydb.cursor()
sql = "SELECT col1, col2, col3, col4, col5 FROM mytable WHERE f_id = %s"
mycursor.execute(sql, (fixed_f_id,))
all_rows = mycursor.fetchall()
# 直接统计所有组合的出现次数
count_map = Counter(all_rows)

# 使用方式和方案1完全一致
print(count_map.get(('a', 'a', 'a', 'x', 1), 0))

方案3:内存SQL查询(匹配你提到的ColdFusion特性)

如果需要用标准SQL对内存数据做二次查询,用Python自带的标准库sqlite3即可实现,无需安装任何第三方依赖:

import sqlite3

fixed_f_id = 123
# 第一步:从MySQL拉取全量f_id对应的数据
mycursor = mydb.cursor()
sql = "SELECT col1, col2, col3, col4, col5 FROM mytable WHERE f_id = %s"
mycursor.execute(sql, (fixed_f_id,))
all_rows = mycursor.fetchall()

# 第二步:创建内存sqlite临时表,写入数据
mem_conn = sqlite3.connect(":memory:")
mem_cursor = mem_conn.cursor()
mem_cursor.execute("CREATE TABLE temp_data (col1 text, col2 text, col3 text, col4 text, col5 int)")
mem_cursor.executemany("INSERT INTO temp_data VALUES (?,?,?,?,?)", all_rows)
mem_conn.commit()

# 第三步:直接用SQL查询内存数据,和你原来的写法几乎一致
def get_mem_result(col1, col2, col3, col4, col5):
    mem_cursor.execute("""
        SELECT COUNT(*) FROM temp_data 
        WHERE col1=? AND col2=? AND col3=? AND col4=? AND col5=?
    """, (col1, col2, col3, col4, col5))
    return mem_cursor.fetchone()[0]

# 使用方式和你原来的函数完全一样
print(get_mem_result('a', 'a', 'a', 'x', 1))
print(get_mem_result('a', 'b', 'a', 'x', 1))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:06:03