首页 > 解决方案 > 使用 IN 运算符比较多列

问题描述

假设我有以下架构:

CREATE TABLE keys (
    keytype INTEGER,
    keyvalue CHARACTER VARYING(30),
    object_id INTEGER NOT NULL
);
CREATE INDEX ix_keys ON keys (keytype, keyvalue);

我想搜索 和 的多种keytype组合keyvalue。一种方法是结合 AND 和 OR,例如:

SELECT object_id FROM keys WHERE
    (keytype=1 AND keyvalue='ALICE') OR
    (keytype=1 AND keyvalue='BOB') OR
    (keytype=2 AND keyvalue='5552319912') OR
    (keytype=3 AND keyvalue='938477') OR
    ...

但是对于库(目前使用 Python psycopg2 但可以是任何人),我想编写一个 SQL 并发送一个元组列表作为参数。是否有运营商这样做并且仍然使用索引?(我知道IN只适用于单列)

我知道这不起作用:

find_keys = [
    (1, 'ALICE'),
    (1, 'BOB'),
    (2, '5552319912'),
    (3, '938477'),
]
cursor.execute("SELECT object_id FROM keys WHERE (keytype, keyvalue) IN %s", (find_keys,))

标签: pythonpostgresqlpsycopg2

解决方案


你实际上很接近。将 find_keys 更改为元组的元组:

find_keys = (
    (1, 'ALICE'),
    (1, 'BOB'),
    (2, '5552319912'),
    (3, '938477'),
)
cur.execute("SELECT object_id FROM keys WHERE (keytype, keyvalue) IN %s", (find_keys,))

您不能使用列表,因为它已被 psycopg2 转换为数组。在 postgres 中比较对象集是有效的。


推荐阅读