Как объединить (удалить и удалить потерянные строки) в tableA
?
tableA
:
+---------+--------+----------+-------+
| company | option | category | rates |
+---------+--------+----------+-------+
| a | f | null | 2.5 |
+---------+--------+----------+-------+
| a | f | d | 2 | *
+---------+--------+----------+-------+
| a | g | e | 3 | **
+---------+--------+----------+-------+
| c | g | e | 4 |
+---------+--------+----------+-------+
| d | f | d | 1 |
+---------+--------+----------+-------+
*
обозначает строку-сироту *.
**
обозначает значение, которое нужно изменить ( 3 -> 4 ).
Прикоснитесь только к компаниям, существующим в tableB
(в данном примере a
& c
, оставьте d
в покое).
tableB
:
+---------+--------+----------+-------+
| company | option | category | rates |
+---------+--------+----------+-------+
| a | f | null | 2.5 |
+---------+--------+----------+-------+
| a | g | e | 4 |
+---------+--------+----------+-------+
| c | g | e | 4 |
+---------+--------+----------+-------+
В обеих таблицах есть уникальный индекс (company, option, category)
.
Желаемый результат tableA
:
+---------+--------+----------+-------+
| company | option | category | rates |
+---------+--------+----------+-------+
| a | f | null | 2.5 |
+---------+--------+----------+-------+
| a | g | e | 4 | <-
+---------+--------+----------+-------+
| c | g | e | 4 |
+---------+--------+----------+-------+
| d | f | d | 1 |
+---------+--------+----------+-------+
Была удалена только вторая строка (a,f,d,2)
, а rates
был изменен с 3 на 4 для (a,g,e)
.
Вот скрипка: https://rextester.com/QUVC30763
Я думаю сначала удалить строку-сироту следующим образом:
DELETE from tableA
USING tableB
WHERE
-- ignore rows with IDs that don't exist in tableB
tableA.company = tableB.company
-- ignore rows that have an exact all-column match in tableB
AND NOT EXISTS
(select * from tableB
where tableB.company is not distinct from tableA.company
AND tableB.option is not distinct from tableA.option
AND tableB.category is not distinct from tableA.category );
Затемсогласен с этим:
INSERT INTO tableA (company, option, category, rates)
SELECT company, option, category, rates
FROM tableB
ON CONFLICT (company, option, category)
DO update
set rates= EXCLUDED.rates
WHERE
tableA.rates IS DISTINCT FROM
EXCLUDED.rates;
Но проблема с функцией upsert заключается в том, что она не может обрабатывать пустые поля.Я должен установить -1
вместо null
, иначе функция не сможет узнать, есть ли дубликаты или нет.Я чувствую, что установка -1
вместо null
создаст много обходных путей в будущем, поэтому я хотел бы избежать этого, если смогу.
Примечание: Я обнаружил, чтоINSERT ... ON CONFLICT ... DO UPDATE
- это, вероятно, правильный путь:
Но я не видел запроса, подходящего для моегодело.И я не уверен, возможно ли это с пустыми полями.Отсюда вопрос:
Есть ли чистый способ слияния с пустыми полями?