我有一个python值列表和一个带有特定列的postgresql表。我想知道我的python列表中的每个元素是否在表中有任何行具有该ID。
例如,假设我有这个python列表:
vals = [4, 8, 15, 16, 23, 42]
以及查询:
select my_col from my_table;
给出:
[4, 5, 6, 7, 8]
然后我想要一个返回的查询:
[True, True, False, False, False, False]
我可以遍历列表并为每个值执行一个新的“select exists”,但我想知道是否有办法在一次调用中执行此操作?
我仅限于postgresql 9.0
答案 0 :(得分:2)
这个问题更多的是关于SQL而不是aboyt Python或psycopg。我会使用类似的查询:
SELECT my_col = ANY(your_array_here) FROM my_table;
获得“表格顺序”或
的结果SELECT A.x = ANY(SELECT my_col FROM my_table)
FROM (SELECT * FROM unnest(your_array_here) x) A;
以“vals order”获得结果。
幸运的是,psycopg提供了一个默认适配器,可以将Python列表转换为PostgreSQL数组,代码非常简单:
curs.execute("SELECT my_col = ANY(%s) from my_table", (vals,))
或:
curs.execute("""SELECT A.x = ANY(SELECT my_col FROM my_table)
FROM (SELECT * FROM unnest(%s) x) A""", (vals,))
请注意,绑定变量参数应该是dict
或元组,并且您希望将完整列表绑定到查询中的单个变量,这意味着您应该使用1元素元组({{1而不是试图直接传递(vals,)
。
答案 1 :(得分:1)
我认为这需要混合使用字符串格式和占位符(因为%s
中每个项目需要一个vals
):
vals = [4, 8, 15, 16, 23, 42]
query = 'select distinct(my_col) from my_table where my_col in ('
query += ', '.join(['%s'] * len(vals))
query += ')'
cursor.execute(query, vals)
theset = {t[0] for t in cursor.fetchall()}
theboollist = [v in theset for v in vals]
此方法应该保证您发送到数据库的数据量(where ... in
子句)和您从中获取的数量都是O(N)
其中N
等于len(vals)
;我认为在大O方面做得比在逻辑上做得更好。