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

时间:2019-03-01 07:27:29

标签: postgresql postgresql-10

如何删除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 ID上的Table B到临时表,然后loop删除每个ID上Table A上不匹配的行。

因为我是PostgreSQL的新手,您能告诉我如何做到这一点吗?我已经搜索了循环删除,但是不确定如何将ID从临时表传递到循环。另外,如果有更好的方法,也请让我知道。预先感谢!

2 个答案:

答案 0 :(得分: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是唯一的

答案 1 :(得分: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有点像“等于”(=运算符),不同之处在于当比较列均为NULL时,它也为true,而row(x,null) = row(x,null)为null,而不是true。至少与您的category列相关,该列在示例数据中为空。