在 sql 查询中将 python 列表作为参数

我有一个蟒蛇名单,比如说

l = [1,5,8]

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

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

我该怎么做?

203442 次浏览

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

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

(谢谢,Blair Conrad)

您需要的 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)) + ')'

地图函数将这个列表转换为一个字符串列表,这些字符串可以使用 Str.join方法用逗号粘合在一起。

或者:

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

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

更新: S · 洛特在注释中提到 PythonSQLite 绑定不支持序列

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))

到目前为止,答案都是将这些值模板化为一个简单的 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)

我喜欢鲍宾斯的回答:

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))

解决@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)+'"'))

例如,如果需要 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(']',')') )

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

l = [1,5,8]


l = tuple(l)


params = {'l': l}


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

enter image description here

我希望这有帮助! ! !

最简单的方法是首先将列表转换为 tuple

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

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

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),))
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)

这应该能解决你的问题。

一个更简单的解决方案:

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


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

如果你在 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)])

请注意,这两个查询计划将转换为相同的查询计划,因此您应该只使用任何更容易的查询计划。例如,如果你的列表是一个元组,使用前者,如果他们存储在一个列表使用后者。

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


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

:var符号看起来更简单

如果列表中的值的数目等于1或大于1,则此操作将起作用

t = str(tuple(l))
if t[-2] == ',':
t= t.replace(t[-2],"")
query = "select name from studens where id IN {}".format(t)

只需使用内联 if 操作和 tuple 函数:

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

要从字符串列表中的字段(而不是 int)运行 select,根据这个问题使用 repr(tuple(map(str, l))):

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


select name
from students
where id in {repr(tuple(map(str, l)))}
'''
print(sql)

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

对于 Oracle 中的日期列表,这种方法是有效的

dates_str = ','.join([f'DATE {repr(s)}' for s in ['2020-11-24', '2020-12-28']])
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')