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 字符串。这对于整数来说完全没问题,但如果我们想对字符串这样做,就会遇到转义问题。
以下是使用参数化查询的变体,适用于两者:
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)
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件