Select 列表中的值不在 table 中?

Select values from a list that aren't in a table?

我想做如下事情;什么是最简单的方法?

SELECT id FROM (1,2,3) WHERE ID NOT IN (SELECT id FROM table)

我的想法不是通过首先将 table ID 加载到脚本中来增加我的 python 脚本的内存使用量。 我能想到的唯一方法是使用 WITH 查询构建一个临时 table,这有点冗长。

select id from (values (1),(2),(3)) as s(id)
except
select id from table

要用 Psycopg 做到这一点:

id_list = ['1','2','3']
q = """
    select array_agg(id)
    from (
        select id from (values {}) s(id)
        except
        select id from table
    ) t;
""".format(','.join(['%s'] * len(id_list)))

print cur.mogrify(q, [(id,) for id in id_list])
# cur.execute(q, [(id,) for id in id_list])

输出:

select array_agg(id)
from (
    select id from (values ('1'),('2'),('3')) s(id)
    except
    select id from table
) t;

提供的答案就像一个魅力,但我无法让它与内置字符串格式的 psycopg2 一起工作,因为每个值在提供的答案中都需要括号,不确定除了构建查询字符串之外还有其他解决方法手动。

q = "select id from (values %s as s(id)
except
select id from table"
cur.execute(q, (id_list,))

以下是可行的替代方案,因为 psycopg2 具有 python list > postgres array converter

select array_agg(ids)
from (
  select unnest(ARRAY['1', '2'])
  except
  select unnest(array_agg(sku::text)) from table
) t (ids);