表中包含产品的图像。每行都指向产品图像的URL。许多产品具有多个图像。
url > Image url
product_id > Product's ID
某些产品的图像重复。我只需要在重复项中保留一个,然后删除该产品的其他重复URL。
我无法对URL进行分组并删除重复项,因为可能会有另一行具有相同的URL并且具有不同的product_id。
TABLE
-
id | product_id | url | is_primary
答案 0 :(得分:0)
根据要删除记录的方式,有几种不同的方法可以实现此目的。最直接的是:
SELECT
DISTINCT ON (product_id)
id
, product_id
, url
, is_primary
FROM table
SELECT DISTINCT从结果中消除重复的行。 SELECT DISTINCT ON消除与所有指定表达式匹配的行。全选(默认)将返回所有候选行,包括重复项。 (请参见下面的DISTINCT条款。)
听起来您可能要使用DISTINCT ON而不是DISTINCT;区别在于DISTINCT ON使您可以返回不同组件的 not 部分的列。
如果您需要做一些更复杂的事情(例如,找到与id
相关联的最小的product_id
),则可以向查询中添加排序,这将通过添加ORDER BY子句来使结果具有确定性
与DISTINCT ON一起使用的ORDER BY子句要注意的是,DISTINCT ON中的所有列必须在ORDER BY中排在最前面。这样就可以找到与每个产品相关联的最小的id
,例如:
SELECT
DISTINCT ON (product_id)
id
, product_id
, url
, is_primary
FROM table
ORDER BY
product_id
, id ASC
根据此表的设置方式,可能会有一个更简单的答案。如果is_primary
是具有部分唯一索引的布尔列(有关更多详细信息,请参见this post和this documentation),则每个{{ 1}},查询如下:
id
之所以提及这一点,是因为这是一种非常好的筛选单个唯一值的方法,如果 这样设置数据库。根据表的大小,它的性能也可能更高,因为Postgres将在磁盘上有一个索引,并且不需要对所有可能的记录进行排序。
如果您的目标是实际上从表中删除重复的记录,那么一种方法是对有效记录进行查询(例如,上述之一),然后将其用作对表的USING子句带有WHERE NOT EXISTS子句的DELETE语句。
答案 1 :(得分:0)
您可以使用EXISTS删除重复项:
delete from tablename t
where exists (
select 1 from tablename
where product_id = t.product_id and url = t.url and id < t.id
)
这将仅是每个product_id
的重复URL之一,其中id
的URL最小。