假设我们有一张桌子:
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);
为什么 Postgres 不使用以下查询删除该行?
DELETE FROM rows WHERE (a, b, c) IN ((1, 1, NULL));
-- DELETE 0
如果其中一列中没有
NULL
值,则它有效:
DELETE FROM rows WHERE (a, b, c) IN ((3, 1, 1));
-- DELETE 1
如果我们尝试使用以下查询之一,也会出现同样的问题:
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
前 3 个查询在每列都不是
NULL
时成功删除行。
所以有2个问题:
NULL
的行?NULL
。NULL
如果您使用,则只能检测到 IS
喜欢
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);
CREATE TABLE
INSERT 0 3
DELETE FROM rows WHERE a= 1 AND b = 1 AND C IS NULL;
DELETE 1
INSERT INTO rows(a, b, c) VALUES (1, 1, NULL)
INSERT 0 1
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) OR (rows.a IS NULL AND to_delete.a IS NULL)) AND
((rows.b = to_delete.b) OR (rows.b IS NULL AND to_delete.b IS NULL)) AND
((rows.c = to_delete.c) OR (rows.c IS NULL AND to_delete.c IS NULL));
DELETE 2