PostgreSQL 10. Как удалить потерянные строки в таблице A только для идентификаторов, существующих в таблице B? - PullRequest
0 голосов
/ 01 марта 2019

Как удалить потерянные строки в 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 (только для идентификаторов проверки a & c, оставьте 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     |
+---------+--------+----------+-------+

Это только пример, реальные таблицы содержатмного других идентификаторов и вариаций.

Я думаю, что я должен group by ID на Table B для временной таблицы, а затем loop удалить на несоответствующих строках на Table A для идентификатора.

Поскольку я новичок в PostgreSQL, можете ли вы показать мне, как это можно сделать?Я искал удаления из цикла, но не уверен, как передать идентификатор из временной таблицы в цикл.Кроме того, если есть лучший способ, пожалуйста, дайте мне знать.Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Вы, кажется, хотите это:

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, тогда как row(x,null) = row(x,null) Нуль, не правда.Это относится, по крайней мере, к вашему столбцу category, который обнуляется в данных выборки.

0 голосов
/ 01 марта 2019
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, идентификатор вводит в заблуждение, обычно идентификатор уникален

...