PostgreSQL 10:如何仅删除表A中仅存在于表B中的ID的孤立行?

问题描述 投票:1回答:2

如何删除Table A中的孤立行*表示孤立行:

+---------+--------+----------+-------+
| ID      | option | category | rates | Table A
+---------+--------+----------+-------+
| a       | f      | null     | 2.5   |
+---------+--------+----------+-------+
| a       | f      | d        | 2     |*
+---------+--------+----------+-------+
| a       | g      | e        | 3     |
+---------+--------+----------+-------+
| c       | g      | e        | 4     |
+---------+--------+----------+-------+
| d       | f      | d        | 1     |
+---------+--------+----------+-------+

仅在Table B中存在的ID(仅检查ID ac,单独留下d):

+---------+--------+----------+-------+
| ID      | option | category | rates | Table B
+---------+--------+----------+-------+
| a       | f      | null     | 2.5   |
+---------+--------+----------+-------+
| a       | g      | e        | 3     |
+---------+--------+----------+-------+
| c       | g      | e        | 4     |
+---------+--------+----------+-------+

结果(仅删除第二行a,f,d,2):

+---------+--------+----------+-------+
| ID      | option | category | rates | Table A
+---------+--------+----------+-------+
| a       | f      | null     | 2.5   |
+---------+--------+----------+-------+
| a       | g      | e        | 3     |
+---------+--------+----------+-------+
| c       | g      | e        | 4     |
+---------+--------+----------+-------+
| d       | f      | d        | 1     |
+---------+--------+----------+-------+

这只是一个示例,实际表包含更多ID和变体。

我的想法是,我应该在group by IDTable B到临时表,然后loop删除Table A每个ID上的非匹配行。

因为我是PostgreSQL的新手,你能告诉我这是怎么做到的吗?我已经搜索了循环删除,但不知道如何将ID从临时表传递给循环。此外,如果有更好的方法,请告诉我。提前致谢!

postgresql postgresql-10
2个回答
1
投票

你似乎想要这个:

DELETE from tableA
 USING tableB
 WHERE 
   -- ignore rows with IDs that don't exist in tableB
   tableA.ID = tableB.ID
   -- ignore rows that have an exact all-column match in tableB
   AND NOT EXISTS (select * from tableB where tableB.* is not distinct from tableA.*);

is not distinct from有点像“equals”(=运算符),除了当比较列都是NULL时它也是真的,而row(x,null) = row(x,null)是null,不是真的。这至少与您的category列相关,可以在样本数据中为空。


1
投票
delete from A using (
select distinct A.* from A, B where A.ID = B.ID   --- all A that have same ID with B
except 
select * from B 
) x   ---- this one has all A rows without B rows only where A.id = B.id
where --- now the join
   A.ID = x.ID and
   A.option = x.option and
   A.category = X.category and
   A.rates = X.rates

最好有一个明确的PK,ID有误导性,通常ID是唯一的

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.