SQL 查询中的 Python 列表作为参数[重复]

2024-12-20 08:37:00
admin
原创
63
摘要:问题描述:我有一个 Python 列表,比如说l = [1,5,8] 我想编写一个 SQL 查询来获取列表中所有元素的数据,比如select name from students where id = |IN THE LIST l| 我如何实现这个目标?解决方案 1:到目前为止,答案都是将值模板化为纯 SQL...

问题描述:

我有一个 Python 列表,比如说

l = [1,5,8]

我想编写一个 SQL 查询来获取列表中所有元素的数据,比如

select name from students where id = |IN THE LIST l|

我如何实现这个目标?


解决方案 1:

到目前为止,答案都是将值模板化为纯 SQL 字符串。这对于整数来说完全没问题,但如果我们想对字符串这样做,就会遇到转义问题。

以下是使用参数化查询的变体,适用于两者:

placeholder= '?' # For SQLite. See DBAPI paramstyle.
placeholders= ', '.join(placeholder for unused in l)
query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders
cursor.execute(query, l)

解决方案 2:

最简单的方法是将列表转到tuple第一个

t = tuple(l)
query = "select name from studens where id IN {}".format(t)

解决方案 3:

不要使它复杂化,解决这个问题很简单。

l = [1,5,8]

l = tuple(l)

params = {'l': l}

cursor.execute('SELECT * FROM table where id in %(l)s',params)

在此处输入图片描述

我希望这有帮助!

解决方案 4:

您想要的 SQL 是

select name from studens where id in (1, 5, 8)

如果你想从python构建这个,你可以使用

l = [1, 5, 8]
sql_query = 'select name from studens where id in (' + ','.join(map(str, l)) + ')'

map函数将使用str.join方法将列表转换为可以用逗号粘合在一起的字符串列表。

或者:

l = [1, 5, 8]
sql_query = 'select name from studens where id in (' + ','.join((str(n) for n in l)) + ')'

如果您更喜欢生成器表达式而不是 map 函数。

更新:S. Lott在评论中提到 Python SQLite 绑定不支持序列。在这种情况下,你可能需要

select name from studens where id = 1 or id = 5 or id = 8

生成者

sql_query = 'select name from studens where ' + ' or '.join(('id = ' + str(n) for n in l))

解决方案 5:

string.join用逗号分隔的列表值,并使用格式运算符形成查询字符串。

myquery = "select name from studens where id in (%s)" % ",".join(map(str,mylist))

(谢谢,布莱尔康拉德)

解决方案 6:

我喜欢 bobince 的回答:

placeholder= '?' # For SQLite. See DBAPI paramstyle.
placeholders= ', '.join(placeholder for unused in l)
query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders
cursor.execute(query, l)

但我注意到了这一点:

placeholders= ', '.join(placeholder for unused in l)

可以替换为:

placeholders= ', '.join(placeholder*len(l))

我觉得这个更直接,虽然不太聪明,也不太通用。这里l需要有一个长度(即引用定义__len__方法的对象),这应该不是问题。但占位符也必须是单个字符。要支持多字符占位符,请使用:

placeholders= ', '.join([placeholder]*len(l))

解决方案 7:

如果您使用带有 Psycopg2 库的 PostgreSQL,您可以让它的元组适配为您完成所有转义和字符串插值,例如:

ids = [1,2,3]
cur.execute(
  "SELECT * FROM foo WHERE id IN %s",
  [tuple(ids)])

即,只需确保将IN参数作为传递即可tuple。如果是,list则可以使用= ANY数组语法:

cur.execute(
  "SELECT * FROM foo WHERE id = ANY (%s)",
  [list(ids)])

请注意,这两者都将变成相同的查询计划,因此您应该只使用更简单的那个。例如,如果您的列表以元组的形式出现,请使用前者,如果它们存储在列表中,则使用后者。

解决方案 8:

只需使用带有元组函数的内联 if 操作即可:

query = "Select * from hr_employee WHERE id in " % tuple(employee_ids) if len(employee_ids) != 1 else "("+ str(employee_ids[0]) + ")"

解决方案 9:

l = [1] # or [1,2,3]

query = "SELECT * FROM table WHERE id IN :l"
params = {'l' : tuple(l)}
cursor.execute(query, params)

:var符号似乎更简单。(Python 3.7)

解决方案 10:

@umounted 答案的解决方案,因为它与单元素元组断开,因为 (1,) 不是有效的 SQL。:

>>> random_ids = [1234,123,54,56,57,58,78,91]
>>> cursor.execute("create table test (id)")
>>> for item in random_ids:
    cursor.execute("insert into test values (%d)" % item)
>>> sublist = [56,57,58]
>>> cursor.execute("select id from test where id in %s" % str(tuple(sublist)).replace(',)',')'))
>>> a = cursor.fetchall()
>>> a
[(56,), (57,), (58,)]

sql字符串的其他解决方案:

cursor.execute("select id from test where id in (%s)" % ('"'+'", "'.join(l)+'"'))

解决方案 11:

一个更简单的解决方案 - 将列表转换为字符串,删除方括号并添加圆括号:

lst = [1,2,3,a,b,c]

query = f"""SELECT * FROM table WHERE IN ({str(lst)[1:-1]})"""

解决方案 12:

要运行选择,其中字段位于字符串列表(而不是 int),按照此问题使用repr(tuple(map(str, l)))。完整示例:

l = ['a','b','c']
sql = f'''

select name 
from students 
where id in ({str(l)[1:-1]})
'''
print(sql)

返回:
select name from students where id in ('a', 'b', 'c')

对于 Oracle 中的日期列表,这有效

l = ['2020-11-24', '2020-12-28']
dates_str = ','.join([f'DATE {repr(s)}' for s in l])
dates_str = f'({dates_str})'

sql_cmd = f'''
select *
from students 
where 
and date in {dates_str}
'''

返回:
select * from students where and date in (DATE '2020-11-24',DATE '2020-12-28')

如果你需要从 pandas df 获取日期列表,那么df['date'].dt.strftime('%Y-%m-%d').unique()

由于我也经常需要它,因此从列表中添加列

# single list
f'select {','.join(l)}'

# multi list in different tables
sql_cmd = f'''
select {','.join(f't1.{s}' for s in l1)},
{','.join(f't1.{s}' for s in l2)},
{','.join(f't2.{s}' for s in l3)}  
'''

解决方案 13:

placeholders= ', '.join("'{"+str(i)+"}'" for i in range(len(l)))
query="select name from students where id (%s)"%placeholders
query=query.format(*l)
cursor.execute(query)

这应该可以解决你的问题。

解决方案 14:

例如,如果您想要 SQL 查询:

select name from studens where id in (1, 5, 8)

那么:

my_list = [1, 5, 8]
cur.execute("select name from studens where id in %s" % repr(my_list).replace('[','(').replace(']',')') )

解决方案 15:

这使用参数替换并处理单值列表的情况:

l = [1,5,8]

get_operator = lambda x: '=' if len(x) == 1 else 'IN'
get_value = lambda x: int(x[0]) if len(x) == 1 else x

query = 'SELECT * FROM table where id ' + get_operator(l) + ' %s'

cursor.execute(query, (get_value(l),))

解决方案 16:

如果列表中的值数量等于 1 或大于 1,则此方法有效

t = str(tuple(l))
if t[-2] == ',':
   t= t.replace(t[-2],"")
query = "select name from studens where id IN {}".format(t)
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1006  
  华为作为全球领先的科技公司,其成功的关键之一在于其高效的研发管理体系——集成产品开发(IPD)。IPD不仅仅是一套流程工具,更是一种团队协作与文化融合的实践体系。通过IPD,华为将跨部门的资源、能力和智慧有效整合,实现了从产品概念到市场交付的全流程高效运作。IPD的核心在于打破传统职能部门的壁垒,强调团队协作与文化的深...
IPD集成产品开发流程   0  
  创新是企业持续发展的核心驱动力,而集成产品开发(IPD, Integrated Product Development)作为一种先进的管理方法,能够帮助企业实现从产品概念到市场落地的全流程优化。通过系统化的流程设计和跨职能团队的协同合作,IPD不仅能够提升开发效率,还能显著降低风险,确保产品在市场上具备竞争力。许多企业...
华为IPD流程   0  
  在快速变化的市场中,企业面临着缩短产品上市时间的巨大压力。消费者需求的多样化和技术的迅猛发展,使得产品生命周期日益缩短。企业必须更快地推出新产品,以抢占市场先机并满足客户期望。然而,传统的产品开发流程往往效率低下,难以应对这种挑战。集成产品开发(IPD)流程作为一种系统化的产品开发方法,能够帮助企业在确保质量的同时,显...
IPD培训课程   0  
  研发IPD(Integrated Product Development,集成产品开发)流程是企业实现高效产品开发的核心方法论之一。它通过跨部门协作、并行工程和结构化流程,确保产品从概念到市场的高效交付。然而,在IPD流程中,绩效评估与改进方法的设计与实施往往成为企业面临的重大挑战。由于研发活动的复杂性和不确定性,传统...
IPD流程分为几个阶段   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用