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

2024-12-20 08:37:00
admin
原创
64
摘要:问题描述:我有一个 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)
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1008  
  在项目管理中,变更是一个不可避免的现象。无论是客户需求的调整、市场环境的变化,还是技术方案的更新,都可能引发项目的变更。如果处理不当,这些变更可能会导致项目延期、成本超支,甚至项目失败。因此,如何有效地应对项目变更,成为项目管理中的核心挑战之一。IPD(集成产品开发)作为一种高效的项目管理方法,其流程图不仅能够帮助团队...
IPD流程中的charter   0  
  IPD(Integrated Product Development,集成产品开发)是华为在长期实践中总结出的一套高效产品开发管理体系。它不仅帮助华为在全球市场中脱颖而出,也成为许多企业提升产品开发效率的参考标杆。IPD的核心在于通过跨部门协作、流程优化和资源整合,实现从需求分析到产品交付的全生命周期管理。通过实施IP...
IPD开发流程管理   0  
  华为IPD(集成产品开发)流程是一种以客户需求为导向、跨部门协同的高效项目管理方法。它通过系统化的流程设计和严格的阶段控制,确保项目从概念到交付的每个环节都能高效运作。IPD流程的核心在于打破传统职能部门的壁垒,将产品开发、市场、销售、供应链等关键环节整合到一个统一的框架中,从而实现资源的优化配置和信息的无缝流动。这种...
IPD流程中TR   0  
  在项目管理的实践中,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节。通过这一评审,项目团队不仅能够验证其数据中心设计和运营的合规性,还能提升整体管理水平。为了确保评审的顺利进行,准备一系列关键文档是必不可少的。这些文档不仅是评审的依据,也是项目团队与评审专家...
华为IPD是什么   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用