从数组中删除不需要的元素

时间:2013-10-22 14:20:15

标签: sql arrays postgresql

我有一张表scraped_listings和一张表scraped_categories。列scraped_listings.categories是一个integer []数组,包含scraped_categories中的行ID。

不知何故(可能是因为我记不起来的错误),一些scraped_listings行的类别中的id不属于类别行(我怀疑这些行已被删除)。

我有以下查询,它给了我受影响的行:

SELECT * FROM scraped_listings a
JOIN (
  SELECT array_agg(id) AS ids
  FROM scraped_categories
  ) b ON NOT a.categories <@ b.ids;

我现在要做的是从categories中删除此查询找到的行无效的ID - 如果数组中的项不是有效的scraped_category id,则应该是丢弃。

我该怎么做?

1 个答案:

答案 0 :(得分:1)

Postgres 9.2或更早

UPDATE scraped_listings s
SET   categories = up.categories
FROM (
    SELECT a.pkey, array_agg(a.id) AS categories
    FROM  (
        SELECT pkey, unnest (categories) AS id
        FROM   scraped_listings
        ) a
    JOIN scraped_categories s USING (id) -- eliminates unwanted ids
    ) up
WHERE s.pkey = up.pkey

pkeyscraped_listings的未公开主键列。

在Postgres 9.3 中,您可以将LATERAL用于相关的unnest()

UPDATE scraped_listings s
SET   categories = up.categories
FROM (
    SELECT a.pkey, array_agg(a.id) AS categories
    FROM  (
        SELECT pkey, c_id AS id
        FROM   scraped_listings l, unnest(l.categories) c_id  -- implicit LATERAL
        ) a
    JOIN scraped_categories s USING (id) -- eliminates unwanted ids
    ) up
WHERE s.pkey = up.pkey

或者您安装了额外的模块intarray,该模块为int[]提供了额外的运算符,例如:

int[] - int     int[]   remove entries matching right argument from array