如何在Python中写入SQL循环所有结果?Excel仅导出首个结果问题解决
问题原因
pd.read_sql_query仅会读取SQL语句返回的第一个结果集,而你的WHILE循环会生成4个独立的结果集,因此只有1/3对应的第一个结果被存入DataFrame,最终Excel仅显示这一个表格。
解决方案
推荐两种实现方式,按需选择:
方式一:逐个读取结果集并写入独立Sheet(无需修改SQL)
利用pyodbc的游标(cursor)遍历所有结果集,将每个结果集转为DataFrame后写入对应日期命名的Sheet:
import pyodbc import pandas as pd from datetime import datetime, timedelta cnxn = pyodbc.connect('DRIVER=xx; SERVER=xx; DATABASE=xx; UID=xx; PWD=xx') cursor = cnxn.cursor() query=""" declare @START_ORDATE DATETIME declare @END_ORDATE DATETIME set @START_ORDATE ='2022-01-03 00:00:00.000' set @END_ORDATE ='2022-01-24 00:00:00.000' WHILE @START_ORDATE<=@END_ORDATE BEGIN select xx,xx,xx... -- 保留你的原有查询逻辑 set @START_ORDATE = @START_ORDATE + 7 END """ cursor.execute(query) writer = pd.ExcelWriter('test1.xlsx') # 处理第一个结果集 start_date = datetime(2022, 1, 3) sheet_name = start_date.strftime('%m/%d') columns = [col[0] for col in cursor.description] df = pd.DataFrame(cursor.fetchall(), columns=columns) df.to_excel(writer, sheet_name=sheet_name, index=False) # 遍历剩余结果集 for i in range(1, 4): if cursor.nextset(): current_date = start_date + timedelta(days=7*i) sheet_name = current_date.strftime('%m/%d') columns = [col[0] for col in cursor.description] df = pd.DataFrame(cursor.fetchall(), columns=columns) df.to_excel(writer, sheet_name=sheet_name, index=False) writer.close() cursor.close() cnxn.close()
关键说明:
- 用
cursor.execute()执行SQL后,通过cursor.fetchall()获取当前结果集 - 调用
cursor.nextset()切换到下一个结果集,直到所有结果处理完成 - 按起始日期+7天的间隔生成Sheet名称(如
1/3、1/10等)
方式二:修改SQL合并结果,再拆分写入Sheet
如果不想调整Python逻辑,可以修改SQL,给每个结果集添加日期标识并合并为一个大结果集,再通过pandas按日期拆分写入Sheet:
修改后的SQL:
declare @START_ORDATE DATETIME declare @END_ORDATE DATETIME set @START_ORDATE ='2022-01-03 00:00:00.000' set @END_ORDATE ='2022-01-24 00:00:00.000' -- 创建临时表存储所有结果 CREATE TABLE #TempData ( RecordDate DATE, -- 替换为你的实际查询列,比如: col1 INT, col2 VARCHAR(50), ... ) WHILE @START_ORDATE<=@END_ORDATE BEGIN INSERT INTO #TempData SELECT CAST(@START_ORDATE AS DATE) AS RecordDate, xx, xx, xx... -- 你的原有查询列 FROM 你的表名 SET @START_ORDATE = @START_ORDATE + 7 END -- 返回合并后的所有数据 SELECT * FROM #TempData DROP TABLE #TempData
对应的Python代码:
import pyodbc import pandas as pd cnxn = pyodbc.connect('DRIVER=xx; SERVER=xx; DATABASE=xx; UID=xx; PWD=xx') query = "上述修改后的SQL语句" df = pd.read_sql_query(query, cnxn) writer = pd.ExcelWriter('test1.xlsx') # 按日期分组,写入对应Sheet for date_val, group in df.groupby('RecordDate'): sheet_name = date_val.strftime('%m/%d') # 移除日期列后写入Sheet group.drop('RecordDate', axis=1).to_excel(writer, sheet_name=sheet_name, index=False) writer.close() cnxn.close()
内容的提问来源于stack exchange,提问作者邱芝螢
相关产品推荐
相关产品推荐

