首页 > 解决方案 > 基于pandas数据框的多条件Oracle SQL查询

问题描述

我有以下格式的数据框:

PID 日期1 日期2 细节
17750A 1960 年 3 月 7 日 06/07/2009 A1B3
17758X 1960 年 3 月 7 日 06/07/2009 A1B3
06/09/1961 2013 年 11 月 5 日 A2B2
28363D 1964 年 11 月 20 日 2019 年 5 月 3 日 A1A2
30050A 1961 年 6 月 30 日 2017 年 7 月 18 日 A1B3
1961 年 4 月 11 日 2008 年 10 月 16 日 A2B2

以及一个带有如下表的 Oracle 数据库:

ID 日期A 日期B 笔记
17750A 1960 年 3 月 7 日 06/07/2009 A1B3
1960 年 3 月 7 日 06/07/2009 A1B3
20964Q 06/09/1961 2013 年 11 月 5 日 A2B2
28363D 1964 年 11 月 20 日 2019 年 4 月 3 日 A1A2
1961 年 6 月 30 日 2017 年 7 月 19 日 A1B3
10832Q 1961 年 4 月 11 日 2008 年 10 月 17 日 A2B2

我需要查询数据库以返回另一个 df,其中包含 ID 与 PID 匹配或 (Date1, Date2) 等于 (DateA, DateB) 的任何记录 - 即 df 行中的两个日期都与表行中的两个日期匹配。

到目前为止,我已经成功实现了第一个,但不是第二个。

pid_list = df['PID'].values
nvars = ','.join(f':{i}' for i in range(len(pid_list)))

sql_query = """
            SELECT
                gd.ID,
                gd.DateA,
                gd.DateB,
                gd.Notes
             FROM table1 as gd
            WHERE gd.ID in (%s)
            """ % nvars
            
df_result = pd_read_sql(sql_query, connection, params=pid_list)

如何扩展它以匹配这对日期?有没有办法通过将元组列表作为参数传递来做到这一点,而不是需要遍历日期对?就像是:

sql_query = """
            SELECT
                gd.ID,
                gd.DateA,
                gd.DateB,
                gd.Notes
              FROM table1 as gd
             WHERE gd.pid in (%s)
                OR (Date1 = DateA AND Date2 = DateB)
            """ % nvars, dates

df_result = pd.read_sql(sql_query, connection, params=(pid_list, (Date1, Date2)))

我认为传递给 pd.read_sql() 的参数可能需要是一个字典,但我不确定如何构造它或如何在不迭代的情况下引用 SQL 查询中的不同条目。

标签: pythonsqlpandasoraclecx-oracle

解决方案


您将始终受到 1000 个条目的限制(您可以使用拆分子列表来解决此问题OR)。

对于日期比较,您可以使用多元素IN列表比较,如下面的查询所示

select * from tab
where id in ('17750A','20964Q') or
(dateA,dateB) in ( ( date'1960-07-03', date'2009-07-06'),
                   (date'1961-06-30' , date'2017-07-19'))

推荐阅读