WHERE IN 作为 Postgres 中的子查询

WHERE IN as Subquery in Postgres

我有两个table。 Table 用户有一列 category_ids 作为整数数组 integer[] 存储为 {1001,1002}

我正在尝试获取所有类别的详细信息,但它不起作用。

SELECT * 
FROM categories 
WHERE id IN (Select category_ids from users where id=1)

当我 运行 Select category_ids from users where id=1 我得到的结果是 {1001,1002}。如何将 {1001,1002} 设置为 (1001,1002) 或者我应该更改什么才能在查询之上工作?

您可以使用 =ANY():

SELECT  * 
FROM categories 
    JOIN users ON categories.id =any(category_ids)
WHERE   users.id = 1;

但是你为什么要使用数组?

我会使用 EXISTS 条件:

SELECT * 
FROM categories c
WHERE EXISTS (Select * 
              from users u
              where c.id = any(u.category_ids)
                and u.id = 1);

这可能是最快的选择,但您应该解释分析所有答案以确保。

SELECT *
FROM categories c
WHERE id IN (SELECT unnest(category_ids) from users where id=1)

SELECT *
FROM categories c
JOIN (SELECT unnest(category_ids) AS id from users where id=1) AS foo
ON c.id=foo.id

由于 IN(),第一个查询将删除数组中的重复项,第二个则不会。

我没有测试语法,所以可能会有拼写错误。基本上 unnest() 是一个将数组扩展为一组行的函数,即将数组转换为 table,然后您可以使用它来连接其他 table,或放入 IN () 子句等。相反的是 array_agg() 这是一个聚合函数,returns 一个聚合元素的数组。这两个还是挺方便的。

如果优化器将 =ANY() 查询转换为带有过滤器的序列扫描,那么 unnest() 应该快得多,因为它应该取消数组嵌套并对类别使用嵌套循环索引扫描。

你也可以试试这个:

SELECT *
FROM categories c
WHERE id =ANY(SELECT category_ids from users where id=1)