Aqui estão alguns dados para brincar:
CREATE TABLE a (
a_id int NOT NULL,
a_prop text NOT NULL
);
CREATE TABLE b (
b_id int NOT NULL,
b_prop text NOT NULL
);
INSERT INTO a VALUES (1, 'blah'), (2, 'blah'), (4, 'not this one');
INSERT INTO b VALUES (1, 'blah'), (3, 'blah'), (5, 'not this one');
Agora eu gostaria de escrever uma consulta que retorna:
Uma possibilidade é:
SELECT *
FROM a
FULL OUTER JOIN b ON a_id = b_id
WHERE (a_prop = 'blah' OR a_prop IS NULL)
AND (b_prop = 'blah' OR b_prop IS NULL);
Isso exige que eu escreva OR ... IS NULL
para todos os campos nos quais tenho uma condição. Isso se torna ainda mais detalhado se algumas condições forem intervalos de datas e similares.
Se esta fosse uma junção à esquerda:
SELECT *
FROM a
LEFT JOIN b ON a_id = b_id
WHERE a_prop = 'blah'
AND (b_prop = 'blah' OR b_prop IS NULL);
Eu poderia mover a condição para a ON
cláusula para evitar isso:
SELECT *
FROM a
LEFT JOIN b ON a_id = b_id AND b_prop = 'blah'
WHERE a_prop = 'blah';
Existe uma maneira de fazer isso com a junção externa completa também?
col = 'x' OR col IS NULL
Original:
Usar
col <> x IS NOT TRUE
:Ou filtre antes de participar:
col <> 'x' OR col IS NULL
A primeira versão da pergunta pedia esse predicado.
Original:
Usar
col IS DISTINCT FROM 'x'
:Ou filtre antes de participar:
db<>fiddle aqui - mostrando tudo
Aparte: Em vez de
!=
eu uso<>
, que é o operador padrão em SQL. (!=
é um alias aceito no Postgres.)Outra opção:
db<>violino