eu posso obter o resultado certo usando o where join , com o próximo sql:
WITH fktable1 AS (
SELECT 2 AS id
)
,fktable2 AS (
SELECT 3 AS id
)
SELECT main.*
FROM
-- main data
(
VALUES
(1, NULL, NULL),
(2, 2, NULL),
(3, NULL, 3),
(4, 2, 3),
(5, 4, NULL), -- wrong, not exist fkcol1 in the fktable1
(6, NULL, 5) -- wrong, not exist fkcol2 in the fktable2
) AS main (col1, fkcol1, fkcol2)
, fktable1, fktable2
WHERE
(
fktable1.id = main.fkcol1
OR main.fkcol1 is NULL
)
AND (
fktable2.id = main.fkcol2
OR main.fkcol2 is NULL
);
ele me dá a saída:
col1 | fkcol1 | fkcol2
------+--------+--------
1 | |
2 | 2 |
3 | | 3
4 | 2 | 3
(4 rows)
existe alguma maneira de obter o mesmo por declaração de junção de tabela? tentei encontrar solução e li muitas perguntas existentes, mas sem sucesso.
Você tem uma junção interna com uma condição lá:
Uma pequena variação da resposta de a_horse_with_no_name é:
A
ON
cláusula é um pouco mais curta, mas talvez não tão óbvia. A ideia é que se main.fkcol1 for nulo, f1.id é comparado com ele mesmo. Observe que isso não é válido se id puder ser nulo, portanto, a solução de a_horse_with_no_name também é um pouco mais segura.Para torná-lo null-safe, uma construção como:
ou:
pode ser usado