Não ficou claro para mim por que você faz com o primeiro SELECT, mas o motivo pelo qual você obtém apenas UPDATE
id
é porque você não está selecionando INSERT return. Como mencionado (e vinculado) nos comentários, o Postgres 9.5 suporta a cláusula INSERT ON CONFLICT, que é uma maneira muito mais limpa de usar.
E alguns exemplos de antes e depois da 9.5:
Antes de 9.5:maneira comum de usar COM
WITH u AS (
UPDATE products
SET product_key='test123', count_parts=33
WHERE product_key = 'test123'
RETURNING id
),i AS (
INSERT
INTO products ( product_key, count_parts )
SELECT 'test123', 33
WHERE NOT EXISTS( SELECT 1 FROM u )
RETURNING id
)
SELECT *
FROM ( SELECT id FROM u
UNION SELECT id FROM i
) r;
Após 9.5:usando INSERT .. ON CONFLICT
INSERT INTO products ( product_key, count_parts )
VALUES ( 'test123', 33 )
ON CONFLICT ( product_key ) DO
UPDATE
SET product_key='test123', count_parts=33
RETURNING id;
ATUALIZAÇÃO:
Como sugerido em um comentário, pode haver pequenos contras usando
INSERT .. ON CONFLICT
caminho. Caso a tabela use incremento automático e essa consulta aconteça muito, então
WITH
pode ser uma opção melhor. Veja mais:https://stackoverflow.com/a/39000072/1161463