Digamos que temos uma mesa:
CREATE TABLE rows(
a int NOT NULL,
b int,
c int
);
INSERT INTO rows(a, b, c) VALUES (1, 1, NULL), (2, NULL, 1), (3, 1, 1);
Por que o Postgres não exclui a linha usando a seguinte consulta?
DELETE FROM rows WHERE (a, b, c) IN ((1, 1, NULL));
-- DELETE 0
Funciona se não houver NULL
valor em uma das colunas:
DELETE FROM rows WHERE (a, b, c) IN ((3, 1, 1));
-- DELETE 1
O mesmo problema se tentarmos usar uma das seguintes consultas:
WITH to_delete AS (
SELECT * FROM UNNEST (
ARRAY[1, 2],
ARRAY[1, NULL],
ARRAY[NULL, 1]
) data(a, b, c)
)
DELETE FROM rows
USING to_delete
WHERE
rows.a = to_delete.a AND
rows.b = to_delete.b AND
rows.c = to_delete.c;
-- DELETE 0
WITH to_delete AS (
SELECT * FROM UNNEST (
ARRAY[1, 2],
ARRAY[1, NULL],
ARRAY[NULL, 1]
) data(a, b, c)
)
DELETE FROM rows
WHERE EXISTS (
SELECT 1 FROM to_delete
WHERE
to_delete.a = rows.a AND
to_delete.b = rows.b AND
to_delete.c = rows.c
)
-- DELETE 0
WITH to_delete AS (
SELECT * FROM UNNEST (
ARRAY[1, 2],
ARRAY[1, NULL],
ARRAY[NULL, 1]
) data(a, b, c)
)
DELETE FROM rows
WHERE (a, b, c) IN (SELECT * FROM to_delete)
-- DELETE 0
As 3 consultas anteriores excluíram linhas com sucesso quando cada coluna não o é NULL
.
Portanto, há 2 perguntas:
- Por que essas consultas SQL não excluem linhas onde está uma das colunas
NULL
? - Como resolver isso? Eu uso o CTE onde recebo as linhas que devo excluir. Uma das colunas nessas linhas é sempre
NULL
.
NULL
só pode ser detectado se você usarIS
como
violino