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

如何在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,提问作者邱芝螢

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:40:35