在字典上循环 SQL 查询

Posted

技术标签:

【中文标题】在字典上循环 SQL 查询【英文标题】:Loop SQL Query Over Dictionary 【发布时间】:2019-08-18 03:54:25 【问题描述】:

我有一个 SQL 查询,它使用日历月的第一天和最后一天生成给定月份的数据子集。我一直试图弄清楚如何循环它几个月 - 我有两个列表(一个用于第一个,另一个用于最后几天),两个元组(相同)和一个字典(第一个和最后一个是键和值)所有这些日期 - 并将所有结果存储在一个数据框中,我的处境非常糟糕。

如果我只使用一个列表或元组,我可以循环并获取所有数据 - 然后我可以循环遍历它并获取所有数据。如果我尝试使用两个,它根本不起作用。有没有办法做我想做的事?

fd=['2018-05-01','2018-06-01','2018-07-01']
ld=['2018-05-31','2018-06-30','2018-07-31']
my_dict=dict(zip(fd, ld))
data_check=pd.DataFrame()

fd_d=','.join(my_dict.keys())
ed_d=','.join(['%%(%s)s' % x for x in my_dict])

query= """

SELECT count(distinct ids),first_date, last_date  from table1
where first_date=%s and last_date =%s
group by 2,3
"""
for x in my_dict:
    df=pd.read_sql(query% (fd_d,ed_d),my_dict)
    data_check=data_check.append(df)

【问题讨论】:

添加 - 红移。谢谢! 【参考方案1】:

一般来说,请注意三个最佳做法:

    避免quadratic copy 在循环中使用DataFrame.append。相反,构建一个数据帧列表,一旦在循环之外就被连接起来。

    使用参数化而不是使用 pandas read_sql 支持的字符串连接。这避免了字符串格式和用引号标点的需要。

    停止使用模运算符 % 进行字符串连接,因为它是 de-emphasised(未正式弃用)。相反,请使用上级str.format

具体来说,根据您的需要,使用zip 在两个列表之间逐元素迭代,而不将其分层放在字典中:

query= """SELECT count(distinct ids), first_date, last_date 
          FROM table1 
          WHERE first_date = %s and last_date = %s 
          GROUP BY 2, 3""" 

df_list = []
for f, l in zip(fd, ld): 
   df = pd.read_sql(query, conn, params=[f, l]) 
   df_list.append(df)

final_df = pd.concat(df_list)

或者,通过在表中聚合每个月的第一天和最后一天来避免循环和参数:

query= """SELECT count(distinct ids), first_date, last_date 
          FROM table1 
          WHERE DATE_PART(d, first_date) = 1
            AND last_date = LAST_DAY(first_date)
          GROUP BY 2, 3
          ORDER BY 2, 3""" 

final_df = pd.read_sql(query, conn) 

【讨论】:

以上是关于在字典上循环 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

在PL/SQL中如何用SQL语句查询数据库中所有表的数据数量?

python MySQL执行SQL查询结果返回字典

一个 SQL 查询,还是一个循环中的多个?

循环遍历列表以从 SQL 查询创建多个数据帧

--SQL循环查询表

SQL Server 关于 Table 字典数据的查询SQL